网上有很多关于这题的解析,目前我看到最有的解法就是计数删除法,但代码很抽象,比较难理解,下面我谈谈自己理解,主要是为了加深印象。
public int MoreThanHalfNum_Solution(int [] array) {
//先检验输入是否合法,此处默认输入不合法时也输出为0
if(array.length==0||array==null)
return 0;
int count = 1;
int res = array[0];
for(int i=1;i<array.length;i++){
if(count==0){
res = array[i];
count++;
}else{
if(array[i]==res){
count++;
}else{
count--;
}
}
}
if(isMoreThanHalf(array,res))
return res;
return 0;
//检测总次数是否超过数组长度的一半
}
private boolean isMoreThanHalf(int[] arr,int res){
int count = 0;
for(int i=0;i<arr.length;i++){
if(arr[i]==res)
count++;
}
if(count*2>arr.length)
return true;
return false;
}
计数删除法的核心是每次删除数组中不同的两个数,则数组剩下的元素中原先占据一半以上的元素不会改变,当最后只剩下一个元素的时候,就是我们想要的结果。
我们用数组{1,2,1,3,1,4,1,5,1}举例说明。首先我们定义 count = 1, res = array[0] = 1, 可以认为它表示当前待删除元素是 res= 1, 且数量是1; 接着继续遍历数组,此时count = 1, 我们需要比较下一个元素array[1] 和res 是否相等,相等的情况下,count ++,count = 2, 意味着待删除元素res存在两个,继续遍历下一个元素; 不相等的话,意味着我们找到了要删除的另外一个元素,此时 count--, 显然,属于第二种情况,我们删除了两个元素,此时 count = 0;
数组遍历到第三个元素,此时count ==0 ,表示待删除元素个数为 0 ,所以无论如何,都要把当前元素标记为待删除元素 res= arr[2] , count = 1;以此类推直至遍历结束,res 就是我们想要的结果。
过程中最重要的是对 count 的理解,它表示的是当前待删元素的个数, count==0时意味着待删除元素个数为0,所以下一个元素一定要标记为待删除元素,且令 count = 1; count!=0 时,我们需要判断下一个元素是否与待删除元素相同,相同的话,count++; 不同时表示我们找到了另外一个单删除的元素,此时可以进行删除, count--;