1. 程式人生 > >劍指offer——陣列中出現次數超過一半的數字(39題)

劍指offer——陣列中出現次數超過一半的數字(39題)

題目:陣列中有一個字出現的次數超過陣列長度的一半,請找出這個數字。例如,輸入一個長度為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;
}

以上程式碼並未考慮無效輸入。