2021年4月19日 星期一

LeetCode 169. Majority Element [Easy] [C++] 解題筆記

Given an array nums of size n, return the majority element.

The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.

 

Example 1:

Input: nums = [3,2,3]
Output: 3

Example 2:

Input: nums = [2,2,1,1,1,2,2]
Output: 2

 

Constraints:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -231 <= nums[i] <= 231 - 1

 

Follow-up: Could you solve the problem in linear time and in O(1) space?
想法:
        這題要我們找到出現超過總數 1/2 次的數字,最簡單的方式可以用一個 hashmap來紀錄出現過的數字的次數。但這樣空間複雜度會來到 O(n) space。要想在 O(n) time O(1) space 的限制之下完成這題就需要用 Boyer–Moore majority vote algorithm(摩爾投票算法) ,具體如下:
1. 將 nums[0] 設為當前假設的 majority element (res),cnt 計算當前的 majority element 出現的次數。
2. 如果 nums[i] == res 則 cnt = cnt + 1
    如果 nums[i] != res 且 cnt == 0 則 res = nums[i] 且 cnt = 1 (表示之前假設的 majority element 已經遇到跟它出現次數一樣多的相異數字了)
    如果 nums[i] != res 且 cnt > 0 則 cnt = cnt - 1
3. 最後的 res 就會是整個 array 的 majority element

這個算法的概念是假設某一數 A 在 array中出現次數過半,則將出現的每一個 A 跟其他出現的相異的數字配對一起刪除,則最後剩下的數字還是A (因為A的數量過半),所以在這個算法過程中只要是與當前 res 相異的數字就跟當前假設的 majority element 兩兩配對刪掉,如果 cnt 等於 0 表示當前 res 可能不是真的 majority element 就換假設下一個數是 majority element。如果某一個數真的是 majority element 在最後一定會剩下來變成 res。

完整程式碼:
解法一:(O(n) time, O(n) space)

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int threshold = nums.size() / 2;
        map<int, int> cnt;
        int ans;
        for (int i = 0; i < nums.size(); i++) {
            if (++cnt[nums.at(i)] > threshold) {
                ans = nums.at(i);
                break;
            }
        }
        return ans;
    }
};

解法二:(O(n) time, O(1) space):
/* Boyer–Moore majority vote algorithm(摩爾投票算法) */
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = nums[0];
        int cnt = 1;
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i] == res) {
                cnt++;
            }
            else if (cnt > 0) {
                cnt--;
            }
            // cnt == 0
            else {
                cnt = 1;
                res = nums[i];
            }
        }
        return res;
    }
};

沒有留言:

張貼留言