这同样也是一道LeetCode Online Judge上面的题目,属于easy级别,原题如下:
- 题目
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.
- 思路
1. 题目乍一看,找一个数组中出现次数大于长度一般的值,感觉挺简单的,而且题目已经限定好数组非空,并且肯定存在这样的一个值。挥笔一些,内外嵌套两次循环遍历,应该很简单就解决问题了吧:
class Solution { public: int majorityElement(vector<int> &num) { int n = num.size(); int cnt = 0; for(vector<int>::iterator iter1=num.begin() ; iter1!=num.end() ; iter1++) { cnt = 0; for(vector<int>::iterator iter2=num.begin() ; iter2!=num.end() ; iter2++) { if(*iter1 == *iter2) { cnt++; if(cnt > (n/2)) { return *iter1; } } } } } };
一运行,呀,又超时了!!!!!想想,也对,时间复杂度为:N2,是不够优化。好吧,再想想,再参考参考百度……
2. 网上牛人可真多啊,提供的思路如下:对于Majority Element来说,它的个数超过了所有其它元素的总和。所以,对一个数遇到的次数进行计数,遇到相同的,次数加1,遇到不同的次数减1。如果计数值为0了,那么换一个数组中的元素进行计数,直到最后剩下计数值不为0的元素,就是要找的。可以想想,假若之前出现过其它的元素用于计数,设为a,那么a的次数肯定会被减为0;而若中间出现过Majority Element,但是计数被减为0了,这里可以想想,剩下的元素中,Majority Element剩余的个数肯定也是大于剩余长度的一半的,因为既然前面都被消灭光了,前面出现的次数肯定小于等于前面长度的一半,剩余的长度里面出现的次数肯定大于剩余长度的一般的。程序如下:
class Solution { public: int majorityElement(vector<int> &num) { int n = num.size(); int cnt = 0; int elem = 0; for(vector<int>::iterator iter=num.begin() ; iter !=num.end() ; iter++) { if(cnt == 0) //HFY::表示前一个元素不是majority element { elem = *iter; cnt++; //HFY::此处要cnt++,使得即使后面为有相同数目不相等的,也能维持为该数 } else { if(elem == *iter) { cnt++; } else { cnt--; } } } return elem; } };
3. PS:也有人提出可以对所有元素进行排序,那么中间那个数一定是Majority Element。想法很精妙,但是时间复杂度大于2中的想法
sort(num.begin(),num.end()); return num[nun.size()/2];
又到了总结时间了,对于一个思维不太灵活的我来说,每次看到广大牛人提供的方法时,都有点叹为观止,希望接下来做题目时,能够也学会类似的思维,能够巧妙地解决问题!!!一个女程序员的编程之路!!!Fighting女汉纸!!!!!