zoukankan      html  css  js  c++  java
  • 剑指offer-数组中出现次数超过一半的数字

     考完试,做完课设后继续来做题。

    题目:数组中出现次数超过一半的数字

    题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

     

    思路分析:剑指offer 上的题感觉都不难,我其实很想做那种能思考良久,最终想到答案,答案又是很巧妙的那种题。而这样的题无非是对语言特性或是一点点数据结构的考察,对这个题而言有多种方法。

    方法一:利用数组结合题目要求进行分析,实际上这个题就是给你一个数组,看是否存在这样一个数,它的个数大于数组中所有元素数的一半,有的话就输出这个数,没有的话就输出0。如果存在这个数,那么它出现的次数比其他所有数字出现的次数和还要多。由于数组本身是无序的,先对数组进行遍历,在遍历数组时保存两个值:一是数组中一个数字,一是次数。遍历下一个数字时,若它与之前保存的数字相同,则次数加1,否则次数减1;若次数为0,则保存下一个数字,并将次数置为1。遍历结束后,所保存的数字即为所求。然后再判断它是否符合条件即可。由于只进行了数组的遍历,所以时间复杂度就是O(n)

    代码如下:

     1 public class Solution {
     2     public int MoreThanHalfNum_Solution(int [] array) {
     3         if(array.length==0)return 0;
     4         int count=1,num=array[0];
     5         for(int i=1;i<array.length;i++){
     6             if(array[i]==num)count++;
     7             else count--;
     8             if(count==0){
     9                 num=array[i]; 
    10                 count=1;
    11             }          
    12         }
    13         count=0;
    14         for(int i=0;i<array.length;i++){
    15             if(array[i]==num)count++;
    16         }
    17         if(count*2>array.length){
    18             return num;
    19         }
    20         else return 0;
    21     }
    22 } 

    方法二:由于数组本身是无序的,那我当然也可以通过排序来得到我想要的结果,java自带的sort方法即可对数组进行排序,其使用的是快排的思想,所以时间复杂度为O(nlogn)

    如果存在这样一个数,那么,在我排序后,在数组的中间位置必定有它,那么我便已经知道了这个数,只需再求其出现的次数进行验证即可

    代码如下:

     1 import java.util.Arrays;
     2  
     3 public class Solution {
     4     public int MoreThanHalfNum_Solution(int [] array) {
     5         Arrays.sort(array);
     6         int count=0;
     7          
     8         for(int i=0;i<array.length;i++){
     9             if(array[i]==array[array.length/2]){
    10                 count++;
    11             }
    12         }
    13         if(count>array.length/2){
    14             return array[array.length/2];
    15         }else{
    16             return 0;
    17         }
    18          
    19     }
    20 }

    方法三:使用hashmap

    hashmap方法简单明了,直接把每个数和它对应的次数存下来,然后对整个hashmap进行遍历,找出次数超过数组的长度一半的那个键

     1 public class Solution {
     2     public int MoreThanHalfNum_Solution(int [] array) {
     3         HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
     4          
     5         for(int i=0;i<array.length;i++){
     6              
     7             if(!map.containsKey(array[i])){
     8                map.put(array[i],1);
     9             }else{
    10                 int count = map.get(array[i]);
    11                 map.put(array[i],++count);
    12             }
    13         }
    14         Iterator iter = map.entrySet().iterator();
    15         while(iter.hasNext()){
    16             Map.Entry entry = (Map.Entry)iter.next();
    17             Integer key =(Integer)entry.getKey();
    18             Integer val = (Integer)entry.getValue();
    19             if(val>array.length/2){
    20                 return key;
    21             }
    22         }
    23         return 0;
    24 }

    感觉这种方法考察的主要是对hashmap的遍历

    简要回顾一下hashmap的遍历方法:

    法1:利用foreach 取出map.entrySet()并获取key和value

    1  Map<String, String> map = new HashMap<String, String>();
    2  for (Entry<String, String> entry : map.entrySet()) {
    3      entry.getKey();
    4      entry.getValue();
    5  }

    法2:调用map.entrySet()的集合迭代器,通过hasNext()方法判断是否有元素可迭代

    1 Map<String, String> map = new HashMap<String, String>();
    2 Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
    3  while (iterator.hasNext()) {
    4      Map.Entry<String, String> entry = iterator.next();
    5      entry.getKey();
    6      entry.getValue();
    7  }

    法3:通过HashMap中的keySet()方法获取key集合,通过循环获取value

    1 Map<String, String> map = new HashMap<String, String>();
    2 for (String key : map.keySet()) {
    3     map.get(key);
    4 }

    法4:通过临时变量保存map.entrySet(),遍历输出

    1 Map<String, String> map = new HashMap<String, String>();
    2 Set<Entry<String, String>> entrySet = map.entrySet();
    3 for (Entry<String, String> entry : entrySet) {
    4     entry.getKey();
    5     entry.getValue();
    6 }

    参考:hashmap的遍历方法总结

  • 相关阅读:
    树形结构的数据库表Schema设计-基于左右值编码
    windows下的coreseek安装及PHP调用入门
    C#string详解
    C#(Wpf)实现小键盘
    c#实现任务栏添加控制按钮
    c#解析Lrc歌词文件
    wpf仿QQ之窗体翻转
    C#(wpf)迷你词典
    wpf常见枚举收集
    最新百度音乐api
  • 原文地址:https://www.cnblogs.com/pathjh/p/9289693.html
Copyright © 2011-2022 走看看