陣列中出現次數超過一半的數字
阿新 • • 發佈:2020-08-23
陣列中出現次數超過一半的數字
陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。
你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。
示例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; } }