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的遍历方法总结

  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/pathjh/p/9289693.html
Copyright © 2011-2022 走看看