您的位置:首页 > 其它

每日一道算法题:数组中出现次数超过一半的数字

2014-12-09 22:32 417 查看
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过了数组长度的一半,因此输出2。

解题思路:如果某个数字在数组中出现的次数超过了数组长度的一半,我们将数组排序后,数组中间的数字必为次数。按照这种思路,我们先将数组排序,再直接输出数组中间的数即可,代码如下:

#include <iostream>
using namespace std;

int partition(int *arr, int begin, int end){
int i = begin;
int j = end;
while (i < j){
while (i < j && arr[i] <= arr[j]){
i++;
}
if (i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
while (i < j && arr[i] <= arr[j]){
j--;
}
if (i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
return i;
}

void quicksort(int *arr, int begin, int end){
if (begin >= end){
return;
}
int p = partition(arr, begin, end);
quicksort(arr, begin, p-1);
quicksort(arr, p+1, end);
}

int main(){
int array[] = {3,2,4,5,3,1,2,3,3,3,3};
quicksort(array, 0, sizeof(array)/sizeof(array[0])-1);
for (int i = 0; i < sizeof(array)/sizeof(array[0]); i++){
cout << array[i] << " ";
}
cout << endl;
cout << "次数超过数组一半的数字是: " << array[(sizeof(array)/sizeof(int))/2] << endl;

system("pause");
return 0;
}
这种思路的时间复杂度主要依赖于排序算法的时间复杂度,即O(nlog(n))。我们再来考虑另外一种思路:依据题目意思,我们需要寻找的那个数出现的次数减去其他数字出现次数之和必定>=1,这样,从数组中每次取出两个不同的数字,直到数组最后取不出不同的数字为止,而每次取出的两个不同数字中不管包不包含我们需要寻找的那个数,最终数组剩余的同样的数字必定是需要的那个数。代码如下:

#include <iostream>
using namespace std;

int partition(int *arr, int left, int right){
int temp = arr[left];
while (left < right){
while ((left < right) && arr[right] >= temp){
right--;
}
arr[left] = arr[right];
while ((left < right) && arr[left] <= temp){
left++;
}
arr[right] = arr[left];
}
arr[left] = temp;
return left;
}

bool check(int *arr, int len, int result){
int count = 0;
for (int i = 0; i < len; i++){
if (arr[i] == result){
++count;
}
}
bool flag = true;
if (count * 2 <= len){
flag = false;
}
return flag;
}

int half_array(int *arr, int left, int right, int length){
if (arr == NULL || length <= 0){
return -1;
}
int index = partition(arr, left, right);
int mid = length/2;
while (index != mid){
if (index > mid){
index = partition(arr, left, index - 1);
}
else{
index = partition(arr, index + 1, right);
}
}
int result = arr[mid];
if (!check(arr, length, result)){
return -1;
}
return arr[mid];
}

int main(){
int arr[] = {2,1,3,1,1};
int length = sizeof(arr)/sizeof(arr[0]);
int half = half_array(arr, 0, length-1, length);
cout << "超过数组一半的数字是: " << half << endl;

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: