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