剑指offer-数组中出现超过一半的数字

剑指offer-数组中出现超过一半的数字

题目描述

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

解题思路

1、方式一:利用map映射。找出超过数组长度一半的数字,关键在于将值和次数进行一个映射。这时我们就可以想到Map<Key,Value>进行映射,Key对应的是值,而Value对应的是对应值出现的次数。
2、利用哨兵,声明一个和数组一样大小的标志位数组,所有位置的值都设置为1,我们遍历下标0到下标数组长度/2的值,当后面的数和当前一个数值相同,我们就加1,不同就减1,如果最后再次遍历标志位数组,发现有大于0位置的值,我们返回这个值。
值得注意的是我们要对特殊情况进行单独讨论,如果数组大小为1.直接返回这个值,但是上面的方法如果数组大小为奇数值(除去大小为1的情况),就有可能返回错误答案,如{1,2,3,4,5,6,7}就会返回3,因为4的标志位1,但是他并不满足要求。所以我们必须看数组长度/2位置的数是否所以的数和它相同,只有这样才能返回这个数,所以必须单独讨论。

代码块1-利用map映射

import java.util.HashMap;


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

代码块二-设立哨兵

import java.util.HashMap;


public class Solution {
    public static int MoreThanHalfNum_Solution(int [] array) {
		int[] count=new int[array.length];
		if(array.length==1) return array[0];
        boolean flag=true;
        for(int i=array.length/2+1;i<array.length;i++){
            if(array[i]!=array[array.length/2]){
                flag=false;
            }
        }
        if(flag){
            return array[array.length/2];
        }
		for (int i = 0; i < array.length/2; i++) {
            count[i]=1;
			for(int j=i+1;j<array.length;j++){
				if(array[i]==array[j]){
					count[i]++;
				}
				else{
					count[i]--;
				}
			}
		}
		for (int i = 0; i < count.length/2; i++) {
			if(count[i]>0){
				return array[i];
			}
		}
		return 0;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值