1. 程式人生 > 實用技巧 >劍指 Offer 39. 陣列中出現次數超過一半的數字

劍指 Offer 39. 陣列中出現次數超過一半的數字

思路

下文使用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 };