问题:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。数组
分析:看到此题第一反应就是将数组中的数字进行排序,而后统计数字出现的次数。排序的时间复杂度为O(nlogn)。spa
从另外一个角度出发,数组中有一个数字出现的次数大于数组长度的一半,也就是说它出现的次数比其余数字出现次数之和还要多。所以能够在遍历数组的时候保存两个值:(1)保存数组中的值;(2)保存数字出现的次数。code
步骤:(1)当遍历的下一个数字与以前保存的数字不一样时, 将次数减1;blog
(2)当遍历的下一个数字与以前保存的数字相同时, 将次数加1;排序
(3)当次数为0时,保存下一个遍历的数字,而且次数置为1。class
因为咱们要找的数字比其余数字出现的次数之和还要多,那么要找的数字确定是最后一次将次数置为1的数字。遍历
package com.wyl; /** * 寻找数组中出现次数超过数组长度通常的数组 * @author wyl * */
public class MoreThanHalfNum { /** * 遍历数组的时候保存两个值:一个是数组中的值,一个为次数 * 遍历数组,若是遍历的下一个数字和以前保存的值不同时, 次数减1; * 若是和以前保存的值相同的时候,次数加1; * 若是次数为0时,保存下一个数字,而且次数设为1 * */
public int moreThanHalfNum(int[] array, int length){ if(array == null || length <= 0){ //输入的数组非法
return 0; } int number = 0; //保存数组中的一个数字
int count = 0; //保存数字出现的次数
for(int i=0;i<length;i++){ if(count == 0){ number = array[i]; count = 1; }else if(array[i] == number){ count++; }else{ count-- ; } } if(!checkNumMoreThanHalf(array, length, number)){ return 0; } return number; } /** * 检查数字number在数组array中出现的次数是否大于通常 * @param array * @param length * @param number * @return
*/
private boolean checkNumMoreThanHalf(int[] array, int length, int number) { // TODO Auto-generated method stub
boolean isMoreThanHalf = true; int count = 0; for(int i=0;i<length;i++){ if(array[i] == number){ count++; } } if(count*2 <= length){ isMoreThanHalf = false; } return isMoreThanHalf; } public static void main(String[] args) { MoreThanHalfNum moreThanHalfNum = new MoreThanHalfNum(); int[] a = {1,0,3,0,0,0,5,4,0,3}; int num = moreThanHalfNum.moreThanHalfNum(a, a.length); System.out.println(num); } }