这个题目和leetcode169:多数元素类似。只是leetcode的题目保证数字总是存在的。我们知道这个题目可以使用哈希表来解决,只是在最坏的情况下时间复杂度可能是O(n),即每个元素都只出现一次。所以我们可以变一下思路。
我们首先记住当前数量较多的元素和它出现的次数,当再次遇到此元素时次数+1,当遇到不一样的次数时就-1,而当更改完次数后如果变为了0,说明这个元素很少,那么我们就要更新当前数量较多的元素为新元素。上述过程都是基于一个事实,就是存在的元素出现次数一定比其他所有元素出现的次数总和还要大,那么最后的次数结果肯定是大于0,而结果就是当前出现次数较多的元素。代码如下:
public int majorityElement(int[] nums) {
int cur = nums[0], num = 1;
for(int i = 1; i < nums.length; ++i) {
if(nums[i] == cur) //如果遇到了,增加
num++;
else {
num--; //否则减少
if(num == 0) { //如果变为了0,则更新当前出现次数较多的元素
num++;
cur = nums[i];
}
}
}
return cur;
}
而剑指offer中的题目,并不保证一定存在这样的元素,那么在最后我们获取到cur
时,需要再次遍历一遍,看看它是不是确实出现次数超过一半。因为假设数组元素为[1,2,3,4,5]
,那么结果中的num
肯定是1,cur
为5,但是并不满足。
public int MoreThanHalfNum_Solution(int [] array) {
int cur = array[0], num = 1;
for(int i = 1; i < array.length; ++i) {
if(array[i] != cur) {
num--;
if(num == 0) {
cur = array[i];
num++;
}
} else {
num++;
}
}
num = 0;
for(int i=0; i < array.length; i++) //然后看最后的cur是不是结果
if(array[i] == cur)
num++;
return (num > array.length/2) ? cur : 0;
}