题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路:
- 思路1:对数组进行排序,可以利用桶排序,排完以后再经过O(n)时间就能找出每个数字出现的次数,所以总得时间复杂度为O(nlogn)+O(n)
- 思路2:遍历一遍数组,将数字和对应出现的次数作为key和value存放到hashmap中,然后取出次数超过一半的数字,时间复杂度为O(n),空间复杂度为O(n)
- 思路3:对于次数超过一半的数字,则数组中的中位数一定是该数字,(如果数组中真的存在次数超过一半的数字),时间复杂度为O(n)
- 思路4:遍历数组,记录数组中数字的值和出现的次数,若下一个数字和记录的值一致,则次数加1,否则次数减1,一旦次数减为0,则保存下一个数字,同时将次数置为1,遍历完后,要找的数字肯定是最后一次将次数置为1对应的那个数字,时间复杂度为O(n)
对思路3和思路4进行代码实现
思路3: public int MoreThanHalfNum_Solution(int [] array) { if(array == null||array.length<=0) return 0; int len = array.length; int low= 0; int high = len -1; int index = Partition(array,low,high); int middle = (len-1)/2; while(index!=middle){ if(index>middle){ high = index - 1; index = Partition(array,low,high); } else{ low = index + 1; index = Partition(array,low,high); } } if(checkMoreThanHalf(array,index)) return array[index]; else return 0; } public static boolean checkMoreThanHalf(int[] array,int result){ boolean flag = false; int number = 0; for(int i = 0;i<array.length;i++){ if(array[i]==array[result]) number++; else continue; } if(number*2>array.length) flag = true; return flag; } public static int Partition(int[] a,int low,int high){ int pivot = a[low]; int i = low; while(low<high){ while(low<high&&a[high]>=pivot) high--; while(low<high&&a[low]<=pivot) low++; if(low<high){ int temp = a[high]; a[high] = a[low]; a[low] = temp; } } a[i] = a[low]; a[low] = pivot; return low; }
思路4:
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null||array.length<=0)
return 0;
int count = 1;
int result = array[0];
for(int i = 1;i<array.length;i++){
if(array[i]==result)
count++;
else{
count--;
if(count==0){
result=array[i];
count = 1;
}
}
}
if(checkMoreThanHalf(array,result))
return result;
else
return 0;
}
public static boolean checkMoreThanHalf(int[] array,int result){
boolean flag = false;
int number = 0;
for(int i = 0;i<array.length;i++){
if(array[i]==result)
number++;
else
continue;
}
if(number*2>array.length)
flag = true;
return flag;
}
注意:为了程序的鲁棒性,需要考虑一些特殊情况,比如数组为null、长度为0以及没有次数超过一半的数字。