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

陣列中出現次數超過一半的數字

陣列中出現次數超過一半的數字

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

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

示例1:

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

#include<iostream>
#include<bits/stdc++.h>
#include<cstring>
#include<vector>
#include<map>
using namespace std;

int cmp(pair<int,int>&a,pair<int
,int>&b){ return a.second<b.second; } int main(){ int num; vector<pair<int,int> >vec; cin>>num; map<int,int> mymap; mymap[num]++; while (cin.get()!='\n') { cin>>num; mymap[num]++; } for (map<int,int>::iterator it=mymap.begin(); it != mymap.end(); it++) { vec.push_back(
*it); } sort(vec.begin(),vec.end(),cmp); // for (int i = 0; i < vec.size(); i++) // { // cout<<vec[i].first<<" "<<vec[i].second<<endl; // } cout<<vec[vec.size()-1].first<<endl; }

解題思路:
本題常見解法如下:

雜湊表統計法: 遍歷陣列 nums ,用 HashMap 統計各數字的數量,最終超過陣列長度一半的數字則為眾數。此方法時間和空間複雜度均為 O(N) 。

陣列排序法: 將陣列 nums 排序,由於眾數的數量超過陣列長度一半,因此 陣列中點的元素 一定為眾數。此方法時間複雜度 O(Nlog 2N)。

摩爾投票法: 核心理念為 “正負抵消” ;時間和空間複雜度分別為 O(N) 和 O(1) ;是本題的最佳解法

摩爾投票法:

票數和:由於眾數出現的次數超過陣列長度的一半;若記眾數的票數為+1,非眾數的票數為-1,則一定有所有數字的票數和> 0

票數正負抵消: 設陣列 nums 中的眾數為 x ,陣列長度為 n 。若 nums 的前 a 個數字的 票數和 = 0x,則 陣列後 (n-a)個數字的 票數和一定仍 >0 (即後 (n-a)個數字的 眾數仍為 x)。

class Solution {
    public int majorityElement(int[] nums) {
        int x = 0, votes = 0;
        for(int num : nums){
            if(votes == 0) x = num;
            votes += num == x ? 1 : -1;
        }
        return x;
    }
}