N28_数组中超过一半的数字

题目描述

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

	//设置一个另一个数组存放每个字母的次数。但是时间复杂度太高n平方。
	public int MoreThanHalfNum_Solution(int [] array) {
		int len=array.length;
		int[] b=new int[len];
		for(int i=0;i<len;i++) {
			int count=0;
			for(int j=0;j<len;j++) {
			if(array[j]==array[i]) count++;	
			}
			b[i]=count;
		}
		int result=0;
		for(int i=0;i<len;i++) {
			if(b[i]>(len/2)) {
				result=array[i];
			}
		}
		return result;
    }

	//题目中假设这个数一定存在,则必是排序后的中位数。可以利用O(n)算法得到数组中第k大的数字O(NlogN)并非最优
	//方法二:可以随机选取一个数,利用快排,如果这个数下标正好是n/2则即为,若不是则在左右一次递归查找。
	public int MoreThanHalfNum_Solution2(int [] array) {
		return 0;
		
	}
	public int MoreThanHalfNum_Solution3(int [] array) {
		int shu;int times=1;
		shu=array[0];
		for(int i=1;i<array.length;i++) {
			if(array[i]==shu) {times++;}
			else {
				times--;
				if(times==0) {
					shu=array[i];
					times=1;
				}
			}
		}
		//判断次数是否大于数组长度。
		times=0;
		for(int i=0;i<array.length;i++) {
			if(array[i]==shu) {
				times++;
			}
		}
		return times>(array.length/2)?shu:0;
		
	}
	//方法三:O(n)复杂度。保留两个值,一个是上一次的数字,和次数。如果下一个数字与之前的数字一样则+1,如果不同则减1,
	//若是为0,则保存下一个数字并置将次数为1。
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		N28_MoreThanHalfNum_Solution n28=new N28_MoreThanHalfNum_Solution();
		int []array= {1,2,2,2,5,3,4,2,5,2,2};
		System.out.println(n28.MoreThanHalfNum_Solution(array));
		System.out.println(n28.MoreThanHalfNum_Solution3(array));
	}

}

  

原文地址:https://www.cnblogs.com/kexiblog/p/11137134.html