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

劍指39 陣列中出現次數超過半數的數

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

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

示例1:

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

這題本質是求陣列中第k小的數。因為如果一個數出現次數超過一半,那麼排序後陣列的中位數肯定是它。如果使用排序,那麼需要nlogn的時間。

直接採用二分法去查詢第k小的數。每一次選取一個數(可以直接用最後一個或者第一個數)作為標誌,把比它小的放到前面,比它大的放到後面,即partition的作用。該數最後的位置就是他在排好序的陣列中的位置。如果這剛好是中位數,那麼我們就找到了這個超過半數的數。

要熟練partition的寫法和應用。

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         int len=nums.size();
 5         return find_half(nums,len);
 6     }
 7 
 8     int partition(vector<int>& nums, int start, int end){
 9         if(end==start)
10             return
start; 11 int smaller=start-1; 12 for(int index=start;index<end;index++){ 13 if(nums[index]<nums[end]){ 14 smaller++; 15 if(index!=smaller) 16 swap(nums[index],nums[smaller]); 17 } 18 } 19 ++smaller;
20 swap(nums[end],nums[smaller]); 21 return smaller; 22 } 23 24 int find_half(vector<int>& nums, int len){ 25 int start=0,end=len-1; 26 int pos=-1; 27 pos=partition(nums,start,end); 28 while(pos!=len/2){ 29 if(pos>len/2) 30 end=pos-1; 31 else 32 start=pos+1; 33 pos=partition(nums,start,end); 34 } 35 return nums[pos]; 36 } 37 };