劍指 Offer 39. 陣列中出現次數超過一半的數字
阿新 • • 發佈:2020-11-04
思路
下文使用majority來代表“陣列中出現次數超過一半的數字 ” 。
方法一:雜湊表
遍歷陣列 nums ,用 map 統計各數字的數量,即可找出majority。此方法時間和空間複雜度均為 O(N) 。
1 class Solution { 2 private: 3 unordered_map<int, int> cntMap; 4 public: 5 int majorityElement(vector<int>& nums) { 6 for(int& num: nums) { 7 cntMap[num]++;8 if(cntMap[num] > nums.size()/2) 9 return num; 10 } 11 12 return -1; 13 } 14 };
方法二:排序
將陣列 nums 排序,陣列中點的元素 一定為 majority。時間複雜度為O(nlogn)
1 class Solution { 2 public: 3 int majorityElement(vector<int>& nums) { 4 sort(nums.begin(), nums.end());5 return nums[nums.size()/2]; 6 } 7 };
方法三:Boyer-Moore 投票演算法 (摩爾投票法)
設定一個計數器vote,每遇到一個和當前的數字相同的數字,就讓vote自增,遇到一個和當前數字不一樣的數字,就讓vote--,當vote< 0時,就將majority設定為當前遍歷的數字。因為有一個數字出現次數超過陣列長度的一半,最後得到的必然是該數字。
此方法時間和空間複雜度分別為 O(N)和 O(1),為本題的最佳解法。
1 class Solution { 2 public: 3 int majorityElement(vector<int>& nums) { 4 int vote = 0; 5 int majority = 0; 6 for(int& num: nums) { 7 if(vote == 0) 8 majority = num; 9 if(majority == num) 10 vote++; 11 else 12 vote--; 13 } 14 15 return majority; 16 } 17 };