题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
假设数组有序,则若存在一个数字出现的次数超过数组长度的一半,则有序数组中间的数一定是这个数字。
因此分为以下三步:
1.将数组排序变为有序数组。
2.统计数组中与下标i(数组长度的一半)所指的值相等元素个数。
3.比较该元素个数是否超过数组的一般。
具体步骤
主要代码,使用冒泡排序的方式进行数组排序,时间复杂度为O(n^2).
public static int MoreThanHalfNum_Solution(int [] array) {
int count=array.length/2; int max=0; int t=0; if(array.length<0){ return 0; } for(int i=0;i<array.length;i++) { for(int j=0;j<array.length-1-i;j++) { if(array[j]>array[j+1]) { t=array[j+1]; array[j+1]=array[j]; array[j]=t; } } } for(int i=0;i<array.length;i++) { if(array[i]==array[count]) { max++; } } if(max>count) { return array[count]; } return 0;
}
调用java.util自带的排序函数sort.
public static int MoreThanHalfNum_Solution(int [] array) { int count=array.length/2; int max=0; int t=0; if(array.length<1){ return 0; } Arrays.sort(array); for(int i=0;i<array.length;i++) { if(array[i]==array[count]) { max++; } } if(max>count) { return array[count]; } return 0; }
大佬的思路,若存在元素超过数组的一半,则该元素的个数一定比其他所有元素的个数和还多。
在遍历数组时保存两个值:一是数组中一个数字,一是次数。遍历下一个数字时,若它与之前保存的数字相同,则次数加1,否则次数减1;若次数为0,则保存下一个数字,并将次数置为1。遍历结束后,所保存的数字即为所求。然后再判断它是否符合条件即可。
public static int MoreThanHalfNum_Solution(int [] array) { if(numbers.empty()) return 0; // 遍历每个元素,并记录次数;若与前一个元素相同,则次数加1,否则次数减1 int result = numbers[0]; int times = 1; // 次数 for(int i=1;i<numbers.size();++i) { if(times == 0) { // 更新result的值为当前元素,并置次数为1 result = numbers[i]; times = 1; } else if(numbers[i] == result) { ++times; // 相同则加1 } else { --times; // 不同则减1 } } // 判断result是否符合条件,即出现次数大于数组长度的一半 times = 0; for(int i=0;i<numbers.size();++i) { if(numbers[i] == result) ++times; } return (times > numbers.size()/2) ? result : 0; }
总结
看到题目我的第一想法就是先统计数组中相同元素的个数,结果不知道如何统计,想了半天没想出方法,看到其他人的提示才想到可以通过排序后找中间那个数组元素就是我们要找的元素,直接统计其个数就好,顿时恍然大悟。看到大佬的数组中若存在元素个数超过数组长度一般则该元素的个数一定大于其他所有数组元素的和的思想,emmmm,我的冒泡排序然后查找统计太麻烦了。我还是个菜鸡,继续加油。