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

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字,eg,{1,2,3,2,2,2,5,4,2},输出为2

分析:如果该数组是排序的,则所求数字肯定位于数组中间

思路:可对数组进行排序,判断中间的数出现的次数;可以用HashMap来实现,容易想到,代码也比较简单

剑指offer:1.类似快排,先在数组中选择随机一个数字,然后调整数组中数字的顺序,使得比选中的数字小的都排在它的左边,大的都在右边,如果这个选中的数字刚好下标是n/2,则这个数字就是数组的中位数,如果大于n/2,则中位数在它的左边,如果小于n/2,中位数位于右边;2.数组特点,遍历数组时保存两个值,一个是数字,一个是次数,当遍历下一个数字的时候,如果下一个数字和我们之前保存的数字相同则次数加一,不同则次数减一,如果次数为零则保存下一个数字,由于要找的数字出现的次数比其他所有数字出现的次数还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字

import java.util.*;

public class wr29ArrayMoreHalf {
//	先排序,然后进行判断,若存在满足要求的数,数组中位数一定是该数
	public static int moreThanHalfNum(int []array){
		if(array==null || array.length==0){
			return 0;
		}
		Arrays.sort(array);
		int count=0;
		int result=array[array.length/2];
		for(int i=0;i<array.length;i++){
			if(array[i]==result){
				count++;
			}
		}
		if(count>array.length/2){
			return result;
		}
		else{
			return 0;
		}
	}
//	利用HashMap思想
	public static int moreThanHalfNum2(int []array){
		if(array==null || array.length==0){
			return 0;
		}
		HashMap<Integer,Integer> hashmap=new HashMap<>();
		for(int i=0;i<array.length;i++){
			int count=0;
			if(!hashmap.containsKey(array[i])){
				hashmap.put(array[i], 1);
			}else{
				count=hashmap.get(array[i])+1;
				hashmap.put(array[i], count);
			}
			if(count>array.length/2){
				return array[i];
			}
		}
		return 0;
	} 
//	遍历数组时保存两个值,一个是数组中的数字,一个是次数
	public static int moreThanHalfNum3(int []array){
		if(array==null || array.length==0){
			return 0;
		}
		int len=array.length;
		int times=1;
		int res=array[0];
//		遍历下一个数字时,若与之前保存的数字相同,则次数加1,否则次数减1
		for(int i=1;i<len;i++){
			if(times==0){//	若次数为0,则保存下一个数字,并将次数置为1
				res=array[i];
				times=1;
			}
			else if(array[i]==res){
				times++;
			}
			else{
				times--;
			}
		}
//		遍历结束,所保存的数字即为所求,再判断它是否符合条件
		times=0;
		for(int num:array){
			if(num==res){
				times++;
			}
		}
		if(times>len/2){
			return res;
		}
		else{
			return 0;
		}
	}
//	剑指offer快排思路,参考牛客上大神代码
	public static int solution(int []array){
		if(array==null || array.length==0){
			return 0;
		}
		int length=array.length;
		int middle=length>>1;
		int start=0;
		int end=length-1;
		int index=partition(array,start,end);
		while(index!=middle){
//			下标大于中间,中位数位于左边,左半部分查找
			if(index>middle){
				end=index-1;
				index=partition(array,start,end);
			}
			else{
				start=index+1;
				index=partition(array,start,end);
			}
		}
//		验证是否存在
		int result=array[middle];
		if(!checkMoreThanHalf(array,result)){
			result=0;
		}
		return result;
	}
	public static int partition(int []array,int left,int right){
		int result=array[left];
		if(left>right){
			return -1;
		}
		while(left<right){
			while(left<right && array[right]>=result){
				right--;
			}
			array[left]=array[right];
			while(left<right && array[left]<result){
				left++;
			}
			array[right]=array[left];
		}
		array[left]=result;
		return left;
	}
	public static boolean checkMoreThanHalf(int []array,int number){
		int times=0;
		for(int i=0;i<array.length;i++){
			if(array[i]==number){
				times++;
			}
		}
		boolean flag=false;
		if(times>array.length/2){
			flag=true;
		}
		return flag;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int []array={1,2,3,2,2,2,5,4,2};
		System.out.println(moreThanHalfNum(array));
		System.out.println(moreThanHalfNum2(array));
		System.out.println(moreThanHalfNum3(array));
		System.out.println(solution(array));
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值