数组中超过一半的数(HashMap的用法-get)

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

import java.util.Arrays;

    public int MoreThanHalfNum_Solution(int [] array) {      
        Arrays.sort(array);        
        int count = 0;
        int value = array[array.length/2];
        for(int i=0;i<array.length;i++){
            if(array[i] == value)
                count++;
        }
        if(count > array.length/2)
            return value;
        else
            return 0;
    }

2、基于快排划分的思想

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {        
        int low = 0,high = array.length - 1;
        int index = paritition(array,low,high);
        int mid = array.length/2;
        while(index != mid){
            if(index > mid){
                index = paritition(array,low,index - 1);

            }
            else{
                index = paritition(array,index + 1,high);

            }
        }
        int value = array[index];
        int count = 0;
        for(int i=0;i<array.length;i++){
            if(array[i] == value)
                count++;
        }
        if(count > array.length/2)
            return array[array.length/2];
        else
            return 0;
    }
    public int paritition(int [] array,int low,int high){        
        int value = array[low];
        while(low < high){
            while(low < high && array[high] >= value)
                high--;
            array[low] = array[high];
            while(low < high && array[low] < value)
                low++;
            array[high] = array[low];
        }
        array[low] = value;
        return low;
    }
}

注意:划分partition返回的是一个下标值,这个下标值所对应的数是这次遍历中正确的!而且还有一个特点,这个下标对应值的左边的数全部小于它,右边的数全部大于它!

我一开始的想法是,得到第一个划分的对应的下标值,直接判断这个下标值是不是等于mid,如果相等,ok;如果不等,继续继续partition。
但是:意思是这么回事,但是,怎么进行之后的partition呢?我们必须明确,我们的目标是,找到下标为mid的对应值
我以为每次的A[low]可能都不一样,那么返回的index肯定也不一样。=》这是错误的!!!
eg:第一个数是1,后面的数都大于1,那么,每次进行partition,得到的index都是相同的,如此,便进入了一个死循环中!
那么如何做呢?
注意到,我返回的index在数组中是这个对应数的正确位置,而且这个下标对应值的左边的数全部小于它,右边的数全部大于它!也就是如果下标值index > mid,说明mid下标只需要在0到index-1寻找就行了;。。。
3、HashMap肯定每个人都会写,但是,看这种写法:

import java.util.*;

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {        
        HashMap<Integer,Integer> map = new HashMap();
        for(int i=0;i<array.length;i++){
            if(map.get(array[i]) == null){
                map.put(array[i],1);
            }else{
                map.put(array[i],map.get(array[i]) + 1);                
            }
            if(map.get(array[i]) > array.length/2)
                return array[i];
        }
        return 0;
    }

}

注意:map.get(x)函数,如果map中不包含x,则返回null;如果包含则返回当前元素的数量!最后返回的是x,而不是map。get(x)。
收获:以后再HashMap中插入元素时,先get一下这个元素,判断它是否存在!
3、根据数组的特性,有一个数出现的次数比所有其他数出现次数的和都多(即存在两种数,一种是res,一种不是res)。我们保存两个数:一个是数组中候选的数字number,一个次数count!初始的时候,设置次数为1,如果当前数和保存的数相同,那么次数加一;如果不同,次数减一,如果次数减为0了,那么number保存当前的数,次数count设置为1。代码如下:

import java.util.*;

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {        
       int number = array[0];
        int count = 1;
        for(int i=1;i<array.length;i++){
            if(array[i] == number){
                count++;
            }else{
                count--;
                if(count == 0){
                    number = array[i];
                    count = 1;
                }
            }
        }
        count = 0;
        for(int i=0;i<array.length;i++){
            if(array[i] == number)
                count++;
        }
        if(count > array.length/2)            
            return number;
        else 
            return 0;
    }

}

猜你喜欢

转载自blog.csdn.net/xuchonghao/article/details/80203966