给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例1:
输入: [3,2,3] 输出: 3
示例2:
输入: [2,2,1,1,1,2,2] 输出: 2
class Solution {
public int majorityElement(int[] nums) {
return quickSearch(nums, 0, nums.length - 1, nums.length / 2);
}
private int quickSearch(int[] nums, int lo, int hi, int k) {
// 每快排切分1次,找到排序后下标为j的元素,如果j恰好等于n/2就返回;
int j = partition(nums, lo, hi);
if (j == k) {
return nums[j];
}
// 否则根据下标j与k的大小关系来决定继续切分左段还是右段。
return j > k? quickSearch(nums, lo, j - 1, k): quickSearch(nums, j + 1, hi, k);
}
// 快排切分,返回下标j,使得比nums[j]小的数都在j的左边,比nums[j]大的数都在j的右边。
private int partition(int[] nums, int lo, int hi) {
int v = nums[lo];
int i = lo, j = hi + 1;
while (true) {
while (++i <= hi && nums[i] < v);
while (--j >= lo && nums[j] > v);
if (i >= j) {
break;
}
int t = nums[j];
nums[j] = nums[i];
nums[i] = t;
}
nums[lo] = nums[j];
nums[j] = v;
return j;
}
}
摩尔投票法
首先请考虑最基本的摩尔投票问题,找出一组数字序列中出现次数大于总数1/2的数字(并且假设这个数字一定存在)。显然这个数字只可能有一个。摩尔投票算法是基于这个事实:每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。
class Solution {
public int majorityElement(int[] nums) {
int count = 0, last = 0;
for (int num: nums) {
if (count == 0) {
last = num;
}
count = count + (last == num? 1: -1);
}
return last;
}
}