您的位置:首页 > 其它

[Leetcode] 169. Majority Element 解题报告

2017-06-04 12:42 381 查看
题目

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.
思路

虽然这道题目的官方难度是easy级别,但我感觉这道题目还是值得好好讨论一下,因为这里面可能会涉及到几个很不错的思想和算法。

1、暴力法:就是扫描数组,并记录每个数字出现的次数,一旦发现某一个数字的出现次数超过一半了,就返回。可以采用哈希表记录每个数字出现的次数。算法的时间复杂度是O(n),空间复杂度也是O(n)。然而,该方法只能作为和面试官开聊的开场白,要是作为最终解法就必挂无疑了。

2、基于快速排序的方法:经典的快速排序算法中的partition函数每次会把数组分成两个部分,并把一个值排在正确的位置上。而如果这个位置刚好在n/2处,那么这个数字必然是超过n/2次的数。这种方法同样可以处理寻求第K个的数。该方法的空间复杂度是O(1),但是时间复杂度最坏情况下可能达到O(n^2),平均复杂度是O(nlogn),相当于快速排序了。不过这里基于partition的思想很重要。

3、Moore投票法:设置一个计数器,并维护一个当前出现次数最多的数。在遍历数组的过程中,如果所遍历的数和当前数相等,则计数器加1,否则计数器减1。一旦发现计数器为0,则更新当前数。由于majority element的出现次数大于所有其它数的出现次数之和,所以当遍历完成数组之后,当前数必然是majority element。该算法的时间复杂度是O(n),空间复杂度是O(1),是该问题的最优解和正解。

代码

1、暴力法:

class Solution {
public:
int majorityElement(vector<int>& nums) {
std::unordered_map<int, int> digits_map;
for (int i = 0; i < nums.size(); ++i) {
if (++digits_map[nums[i]] > nums.size() / 2) {
return nums[i];
}
}
return -1;
}
};
2、基于快速排序的方法:

class Solution {
public:
int majorityElement(vec
b16e
tor<int>& nums) {
if (nums.size() == 0) { // special case
return -1;
}
int start = 0, end = nums.size() - 1;
int index = partition(nums, start, end);
while(index != (nums.size() / 2)) {
if(index > nums.size()/2) { // majority element will certainly be in the left part
end = index - 1;
index = partition(nums, start, end);
}
else if(index < nums.size()/2) { // majority element will certainly be in the right part
start = index + 1;
index = partition(nums, start, end);
}
}
return nums[nums.size()/2];
}
private:
int partition(vector<int>& nums, int begin, int end) {
int value = nums[begin];
while(begin < end) {
while(begin < end && value < nums[end]) {
--end;
}
if(begin < end) {
nums[begin++] = nums[end];
}
while(begin < end && value > nums[begin]) {
++begin;
}
if(begin < end) {
nums[end--] = nums[begin];
}
}
nums[begin] = value;
return begin;
}
};
3、Moore投票法:

class Solution {
public:
int majorityElement(vector<int>& nums) {
if(nums.size() == 0) {
return -1;
}
int num = nums[0], count = 1;
for(int i = 1; i < nums.size(); ++i) {
if(nums[i] == num) {
++count;
}
else {
--count;
if(count == 0) {
num = nums[i];
count = 1;
}
}
}
return num;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: