劍指offer——陣列中出現次數超過一半的數字(39題)
阿新 • • 發佈:2018-12-13
題目:陣列中有一個字出現的次數超過陣列長度的一半,請找出這個數字。例如,輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。
解題思想:一定要緊緊抓住輸出數字出現的次數超過陣列長度的一半,這一特性。
如果排序後,最終輸出的數字的下標一定是大於或等於陣列總長度的一半mid。於是我們可以利用快排的核心部分程式碼partition函式,對該函式返回的下標序號與mid比較,如果小於mid時,則將mid+1至end位置上的陣列繼續partition。如果大於mid時,則將0到mid-1位置上的陣列繼續partition。直至返回的下標序號等於mid即結束。
實現程式碼如下:
#include<iostream> #include<vector> using namespace std; /* 快速排序的核心思想 */ int partition(vector<int>& nums, int start, int end) { if (start == end) return start; int tmp = nums[start]; int low = start, high = end; do { while (low < high&&nums[high] >= tmp) high--; if (low < high&&nums[high] < tmp) nums[low++] = nums[high]; while (low < high&&nums[low] <= tmp) low++; if (low<high&&nums[low]>tmp) nums[high--] = nums[low]; } while (low != high); nums[low] = tmp; return low; } int moreThanHalfNum(vector<int>& nums) { int len = nums.size(); int mid = partition(nums, 0, len - 1); int midInd = len >> 2; while (mid != midInd) { if (mid < midInd) mid = partition(nums, mid + 1, len - 1); else mid = partition(nums, 0, mid - 1); } return nums[mid]; } int main() { vector<int> nums = { 1,2,3,2,2,2,5,4,2 }; int ret; ret = moreThanHalfNum(nums); return 0; }
以上程式碼並未考慮無效輸入。