题目:数组中有一个字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为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;
}
以上代码并未考虑无效输入。