【演算法分析與設計】【第五週】169. Majority Element
阿新 • • 發佈:2019-02-02
方法概覽
這題和《演算法概論習題》2.23是一樣的。老師剛講過,複習一下。
題目大意:找到出現次數超過一半的元素。
看到題目,應該想到,給定一個整數陣列,找出出現次數大於N/2 的那個數,且這樣的數若存在,就僅僅存在一個。
方法很多,這裡總結四種。
方法 | 複雜度 |
---|---|
快排 | O(nlogn) |
topK | O(n) |
分治 | O(nlogn) |
投票演算法 | O(n) |
視作中位數問題
首先要明白,如果一個元素的個數超過N/2則這個元素必然是這N個元素的中位數。則題目轉化為找中位數。
方法一(快排)
方法一:最直白的一種,用快排演算法,將該陣列排序,其中中位數就是主元素,這很容易想通。快排O(nlogn),找中位數O(1)快排演算法前兩週寫了多次了,本週就先不寫了。
方法二(topK)
方法二:topK也是剛剛複習過的內容,只不過這裡的K位置比較特殊,第K大是中位數而已。
分治
方法三
方法三:根據2.23的提示,先採取分治的思想,用一種複雜度在O(nlogn)的演算法。
本題最佳
方法四
方法四:多數投票演算法。
思路大致如下:
1.如果count==0,則將now的值設定為陣列的當前元素,將count賦值為1;
2.反之,如果now和現在陣列元素值相同,則count++,反之count–;
3.重複上述兩步,直到掃描完陣列。
在本題中,題目明確了主元素是存在的,簡化了一些步驟,沒有了後邊的檢查步驟。
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> v;
int size = nums.size();
int n1=0,n2=0,cn1=0,cn2=0;
for(int i=0;i<size;i++)
{
if(nums[i]==n1)
{
cn1++;
}
else if(nums[i]==n2)
{
cn2++;
}
else if(cn1==0)
{
n1 = nums[i];
cn1 = 1;
}
else if(cn2==0)
{
n2 = nums[i];
cn2 = 1;
}
else
{
cn1--;
cn2--;
}
}
if(cn2==0&&size>0)//用來解決[0 0]的情況
n2=nums[0]-1;
cn1=0;
cn2=0;
for(int i=0;i<size;i++)
{
if(nums[i]==n1)
cn1++;
if(nums[i]==n2)
cn2++;
}
if(cn1>size/3)
v.push_back(n1);
if(cn2>size/3)
v.push_back(n2);
return v;
}
};
(題目升級)找出現次數多於N/3的元素
依然是多數投票演算法 Majority Vote Algorithm,這裡講解挺詳細。