剑指offerNo28. 数组中出现次数超过一半的数字(Java)

题目描述:

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

思路:

方法一:

借助hashmap存储数组中每个数出现的次数,最后看是否有数字出现次数超过数组长度的一半;

代码:

package offer;

import org.omg.PortableInterceptor.INACTIVE;

import java.util.HashMap;
import java.util.Map;

public class TestNo28_1 {
    public static void main(String[] args) {
        int[] a = {1,2,3,2,2,2,5,4,2};
        System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));
    }
    public int MoreThanHalfNum_Solution(int [] array) {
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int len = array.length;
        for(int i = 0;i<len;i++){ //开始进行遍历  Entry<键,值> 数作为键,出现的次数作为值
            if(!map.containsKey(array[i])){ //如果当前遍历的数不在哈希表中,则将该数加进去<键,1> ‘1’说明该值在哈希表中只有一个
                map.put(array[i],1);
            }else{
                map.put(array[i],map.get(array[i])+1);//如果当前的值已经在哈希表中了,就将该键的值取出来+1
            }
            for(Map.Entry<Integer,Integer> entry :map.entrySet()){ //遍历每一个Entry,进行验证
                if(entry.getValue()>len/2){
                    return entry.getKey();
                }

            }
        }
        return 0;

    }
}

方法二:

对数组先进行排序,如果数组中存在一个长度超过数组一半的数字,那么数组中间的那个数一定是这个数。我们取数组中间的那个数做一下统计,验证一下是否大于数组长度的一半。

代码:

package offer;

import java.util.Arrays;

public class TestNo28_2 {
    public static void main(String[] args) {
        int[] a = {1,2,3,2,2,2,5,4,2};
        System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));

    }
    public int MoreThanHalfNum_Solution(int [] array) {
        Arrays.sort(array); //先对数组进行排序
        int half = array.length/2;
        int count = 0;
        for(int i = 0;i<array.length;i++){ //进行遍历
            if(array[i] == array[half]){  //如果等于中间的那个数,则计数加1
                count++;
            }
        }
        if(count > half) //如果中间那个数的计数大于数组长度的一半,则返回数组中间的值
            return array[half];
        else
            return 0;
    }
}

方法三:

如果数组中存在大于数组长度一半的数字,那么该数的长度肯定大于数组中其它数字长度的综合。比如数组arr{1,2,3,2,2,2,5,4,2}中,2的长度是5,数组中其它数字的长度是4,因此,我们可以这样进行遍历,申请两个变量,一个用于记录当前遍历的数字num,一个用于记录次数count,比如,初始化num=arr[0],count=1,开始进行遍历,当与上一个数字相同的时候进行count++操作,当与上一个数字不相同的时候进行count--操作,当count=0的时候,更新num=arr[i],(i指的是使得count为0的数字)。遍历一遍之后,使得count不等于0的数字应该就是大于数组长度一半的数,之后进行验证即可。

代码:

package offer;

public class TestNo28 {
    public static void main(String[] args) {
        int[] a = {1,2,3,2,2,2,5,4,2};
        System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));

    }
    public int MoreThanHalfNum_Solution(int [] array) {
        int num = array[0],count = 1;  //num用于记录当前遍历的数,初始化为第一个数。count用于记录次数
        for(int i = 1;i<array.length;i++){//开始进行遍历,从当前遍历的下一个数开始
            if(array[i] == num){ //如果遍历的数等于 num
                count++;
            }else{
                count--;
            }
            if(count== 0){ //如果count==0 则更新num为 使count为0的那个数,并且更新count为1
                num = array[i];
                count = 1;
            }
        }
        count = 0; //进行验证,看看找到的那个数的个数是不是大于数组的一半
        for(int i = 0;i<array.length;i++){
            if(array[i] == num){
                count++;
            }
        }
        return count > array.length/2 ? num:0;
    }
}
发布了64 篇原创文章 · 获赞 13 · 访问量 4292

猜你喜欢

转载自blog.csdn.net/qq_40664693/article/details/104417552