给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
解法一:
class Solution {
public static int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length>>1];
}
}
取数组排序后位于中间的元素,这个很容易就能想到。,取位于中间的下标用位运算可以再缩短点时间。
解法二:
摩尔投票法
class Solution {
public int majorityElement(int[] nums) {
int cand_num=nums[0];
int count=0;
for(int num:nums){
if(cand_num==num){
count++;
}else{
if(--count==0){
cand_num=num;
count=1;
}
}
}
return cand_num;
}
}
以数组的第一个元素nums[0]的值为候选人(cand_num),票数(count)初始化为0。
遍历数组,当遇到与cand_num的值相同的数则票数count++,不同则count–。
当票数count为0时,更换候选人,票数count重置为1。
遍历完数组后,cand_num即为最终答案
由于多数元素> ⌊ n/2 ⌋个,那么剩余元素<= ⌊ n/2 ⌋个,
那么 多数元素个数-剩余元素个数>0
可以理解为每个多数元素和剩余元素两两相互抵消,抵消到最后必然会剩余至少一个多数元素。
同时此题中明确给定的数组总是存在多数元素。故不需要考虑[1,2,3]这种情况。
如果考虑此情况,则在遍历出候选人(cand_num)后在,重置票数(count)值为0,再次遍历数组,计算候选人(cand_num)获得的票数(count)是否大于数组长度的一半。
//计算票数,防止出现每个人票数都为1的情况
count=0;
for(int num:nums){
if(cand_num==num){
count++;
}
}
return count>(nums.length>>1)?cand_num:null;