LeetCode 169. Majority Element 解题报告
题目描述
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
示例
没有给出,自己想想就知道题意是什么。
限制条件
没有明确给出。
解题思路
我的思路:
很直观的思路:
- 用一个map保存数组中出现的数字跟出现次数。
- 遍历数组并更新数字及其出现次数,如果某个数字的次数大于数组长度一半就记下该数字,并结束遍历。
- 返回记录的数字
就这样轻松地地通过了,不过惯例看看dicuss,好吧,又一次被大牛们震撼了,简单的题也存在着巧妙的解法。下面讲解大牛们的A Linear Time Majority Vote Algorithm
其他思路1
A Linear Time Majority Vote Algorithm用于找出数组中出现次数最多的元素。这个算法存在很大的限制,就是数组中必须存在出现次数最多的元素,并且次数是大于n/2。刚好这道题说了满足这两个限制,所以可以使用该算法。
算法的核心步骤是遍历一遍数组nums并且维护一组信息(当前元素e,元素次数count)。
- 初始时,当前元素e为第一个元素nums[0],元素次数count=1。
- 从nums[1]开始,如果e与nums[i]不同,元素次数count自减1,如果e与nums[i]相同,元素次数count自增1。
- 当count=0,更新e为目前检测的数组元素nums[i],并且count自增1。
- 最后,e保存的就是出现次数最多的元素。
这种算法使用了最多元素的次数是大于n/2这一条件,其他元素的个数和肯定比n/2小,所以不管它们的个数有多大,遇到了n/2个最大元素e,count都会减为0,从而使得e保存的是出现最多的元素e。
其他思路2
还有一种思路是排序后返回中间的元素,而这种算法同样是利用了最多元素的次数是大于n/2这一条件。在排序时,由于最多的元素e的个数比n/2大,所以肯定会出现在排序后数组的中间位置。
然而有人举出了如下两个例子说明这个算法是错误的
[1,1,2,3]
[1,2,3,3]
但是本身这两个例子存在问题,题目说的是最大次数比 ⌊ n/2 ⌋要大(appears more than ⌊ n/2 ⌋ times),如果是这两个例子,那么最大次数至少要等于3,而这两个例子中最大次数是2=⌊ n/2 ⌋,所以不是正确的测试用例,因此这种算法的思想是正确的。
代码
我的代码
class Solution {
public:
int majorityElement(vector<int>& nums) {
map<int, int> numberTimes;
int threshold = nums.size() / 2;
int major = 0;
for (auto n: nums) {
numberTimes[n]++;
if (numberTimes[n] > threshold) {
major = n;
break;
}
}
return major;
}
};
参考代码1
class Solution {
public:
int majorityElement(vector<int>& nums) {
int major = nums[0], count = 1;
for (int i = 1; i < nums.size(); i++) {
if (count == 0) {
count++;
major = nums[i];
} else if (major == nums[i])
count++;
else
count--;
}
return major;
}
};
参考代码2
class Solution {
public:
int majorityElement(vector<int>& nums) {
int len = nums.size();
sort(nums.begin(), nums.end());
return nums[len / 2];
}
};
总结
这道题抓住了最多次数大于n/2的条件能够有不同的解法,而使用普通的记数方法也可以通过。做完这道题,比较大的收获时开阔了解题的思路,同样解题时要多注意关键的条件,说不定能利用关键条件快速解决问题。
完成第三个坑,继续下一个坑,加油加油!