题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这一个数字。输入一个长度为9的数组{1,2,3,2,2,2,5,4,2},
数字2在数组中出现的次数大于数组长度的一半,返回2。
这道题类似以前做过的
Maximum Subarray。
按着以前的思路:
确定某一个数字,遇到相同的数字加1,遇到不同的数字减1,当累加器为0时,我们重新开始计算即可。
完成后继续判断这个数字有没有出现够一定的次数。
代码如下
public static int moreHalfSimple(int[] num) { int count =1; int index; int result=num[0]; for(index = 1;index<num.length-1;index++) { if(count==0) { result = num[index]; count=1; } if(result != num[index]) count--; else count++; } if(!checkHalf(num,result)) { result=-1;//没找到返回-1 } return result; } //判断数字是否出现了数组一半以上的长度 private static boolean checkHalf(int[] num, int result) { int count=0; for(int i =0;i<num.length;i++) { if(num[i] == result) count++; } if(count*2 <=num.length) return false; return true; }
----------------------------------------------------------------------------------------------------------------------------------------------
看了剑指Offer上面还有一种解法,特意贴上来:
它的思路是:
如果一个数组元素出现的次数大于数组长度的一半,那么这个数组排序后,这个数肯定位于数组中间。即中位数。
我们借用快排的思想,如果最终和轴交换的元素处于数组的中间,那么我们继续判断这个数字是否出现了大于一半的次数。
代码如下:
private static int partition(int []num,int start,int end) { if(num==null || num.length ==0) return -1; int s = num[end]; int minIndex=start-1; int maxIndex=start; for(;maxIndex<end;maxIndex++) { if(num[maxIndex] <= num[end]) { minIndex++; swap(num,minIndex,maxIndex); } } swap(num,minIndex+1,maxIndex); return minIndex+1; } private static void swap(int[] num ,int a ,int b) { int temp = num[a]; num[a] = num[b]; num[b] = temp; } static boolean inputflag= false;//全局变量记录是输入无效还是没找到 public static int moreThanhalf(int[] num,int start,int end) { if(num ==null || num.length==0 ||start>end) { inputflag=true; return -1; inputflag为true且返回-1,说明输入无效 } int result=0; int middle = num.length >> 1; int index; index = partition(num, start, end); while(index != middle) { if(index>middle) { index =partition(num, start, index-1); } else { index = partition(num, index+1, end); } } result = num[middle]; if(!checkHalf(num,result)) { result =0;//返回0且inputFlag为false说明没找到 } return result; } private static boolean checkHalf(int[] num, int result) { int count=0; for(int i =0;i<num.length;i++) { if(num[i] == result) count++; } if(count*2 <=num.length) { inputflag=false; return false; } return true; }