给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3] 输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2] 输出:2
提示:
n == nums.length1 <= n <= 5 *-<= nums[i] <=
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
关键词:排序、 Boyer-Moore 投票算法、 分治
思路:
①排序:这应该是最容易想到的方法了,由于题目保证了多数元素(后面称众数)一定存在,那么如果将数组从小到大排序,中间位置一定就是答案。使用效率较高的排序算法可以将时间复杂度控制在nlogn,空间复杂度为O(1)。
题解如下:
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[(nums.size() - 1) / 2];
}
};
② Boyer-Moore 投票算法:这个看官方题解挺难理解的,但是评论区老哥给的理解方法很好。假设一个数字代表一个阵营的士兵,相同数字则属于相同的阵营。每一个士兵都要冲上阵地去抢夺这个阵地,如果当前阵地上没有其他阵营的士兵,则该士兵将己方的旗帜插在阵地上,该阵地归属该阵营;否则,该士兵将会和阵地上的其他阵营的一名士兵同归于尽。由于题目保证存在众数,我们举一个极端的例子:总共有100个数,其中有51个数是1,有49个数是2。即只有两个阵营。那么最后会留下两个1阵营的士兵,此时阵地一定属于1阵营。
题解如下:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int cnt = 1, lord = nums[0];
for(int i = 1; i < nums.size(); ++i) {
if(nums[i] == lord) cnt++;
else {
if(cnt == 0) {
lord = nums[i];
cnt++;
}
else cnt--;
}
}
return lord;
}
};
这种方法只用遍历一遍nums数组,时间复杂度为O(n);只需要常数个辅助变量,空间复杂度为O(1)。
③分治:有一个结论就是,如果某个数是全局的众数,那么从中间划分成左右两个子数组后,这个数一定也是某一子数组的众数。一直划分至区间长度为1,返回区间内的这个数。如果左右两个区间的众数一样,则该数就是合并后的区间的众数;否则,计算这两个数在合并区间内出现的次数,哪个出现次数多就返回哪个。
题解如下(leetcode上没过,在nums=[3,3,4]的时候,说我的算法返回值是4。然而我自己推演的结果应该是3,让Deepseek帮我推演的结果也是3。。。难绷):
class Solution {
public:
int majorityElement(vector<int>& nums) {
return get(nums, 0, nums.size() - 1);
}
int get(vector<int>& nums, int left, int right) {
if(left == right) return nums[left];
int mid = left + (right - left) / 2;
int leftMax = get(nums, left, mid);
int rightMax = get(nums, mid + 1, right);
if(leftMax == rightMax) return leftMax; // 左右区间内的众数相同,则该数一定是全局的众数
// 否则在全局内比较leftMax和rightMax的出现次数,返回出现次数大的
int leftcnt = count(nums, left, right, leftMax);
int rightcnt = count(nums, left, right, rightMax);
return leftMax >= rightMax ? leftMax : rightMax;
}
int count(vector<int>& nums, int left, int right, int target) {
int cnt = 0;
for(int i = left; i <= right; i++) {
if(nums[i] == target) cnt++;
}
return cnt;
}
};

被折叠的 条评论
为什么被折叠?



