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

有夢想的coder發表於2020-11-24

陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。

你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。

示例 1:

輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
輸出: 2

限制:

1 <= 陣列長度 <= 50000

方法一:利用 hashmap 儲存陣列中值的出現次數。先放C++程式碼,思路簡單易懂。

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        unordered_map<int, int> match;
        int len = nums.size(), res = 10086;
        if(len == 1 || len == 2){
            return nums[0];
        }

        for(int i = 0; i < len; ++i){
            match[nums[i]] ++;
            if(match[nums[i]] > (len / 2)){
                res = nums[i];
                break;
            }
        }
        return res;
    }
};

int main()
{   
    vector<int> myvector{1, 2, 3, 2, 2, 2, 5, 4, 2};
    Solution S;
    cout<<S.majorityElement(myvector)<<endl;
    system("pause");
    return 0;
}

在這裡插入圖片描述

方法二:摩爾投票法(本題最佳解法)。其實就是諸侯亂戰,你作為東方大國,擁有超過總數 1/2 的兵力,且規定一個兵打一個兵必定同歸於盡,那麼即使全部諸侯打你一個,最後剩下的兵肯定也是你的兵,也就是你贏了。

所以我們的策略就是,先讓 res = nums[0],mole_vote = 1,然後往後迭代。但凡遇到下一個不等於 res,就讓 mole_vote --(相當於和一個敵人同歸於盡);如果下一個等於 res,則mole_vote ++。如果 mole_vote == 0 了,就讓 res 等於當前 numes[i]。
先放C++程式碼,思路簡單易懂。

#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int moleVote = 0, res = 0;
        for(int i : nums){//for 迴圈
            if(moleVote == 0){
                res = i;
            }
            moleVote += res == i ? 1 : -1;//比較巧妙的投票法
        }
        return res;
    }
};

int main()
{   
    vector<int> myvector{1, 2, 3, 2, 2, 2, 5, 4, 2};
    Solution S;
    cout<<S.majorityElement(myvector)<<endl;
    system("pause");
    return 0;
}

在這裡插入圖片描述

相關文章