题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
遍历数组,用一个map统计每个数字出现的次数。最后遍历map,判断计数是否大于数组size的一般。
时间复杂度o(n),空间复杂度o(n)。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int nSize = numbers.size();
if(nSize == 0) return 0;
map<int, int> mymap;
map<int, int>::iterator iter;
//int num = 0;
for(int i = 0; i < nSize; i++)
{
iter = mymap.find(numbers[i]);
if(iter != mymap.end())
mymap[numbers[i]]++;
else
mymap.insert(pair<int, int>(numbers[i], 1));
}
for(iter = mymap.begin(); iter != mymap.end(); iter++)
{
if(iter->second > (nSize/2))
return iter->first;
}
return 0;
}
};
时间复杂度O(nlogn)的算法
换个角度,如果一个数在数组中出现次数超过一半,那么它一定位于排序数组的中间,即中位数。
现在给出的数组是无序的,先排序(部分排序)找中位数,然后看其在数组中出现次数是否大于一半。
找中位数: Partition 实现遍历一遍之后某个数左边的数都比它小,右边的数都比它大。
快速排序就是基于Partition 实现的。
#include<cstdlib>
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int nSize = numbers.size();
if(nSize == 0) return 0;
int middle = nSize >> 1;
int start = 0;
int end = nSize - 1;
int index = Partition(numbers, nSize, start, end);
while(index != middle)
{
if(index > middle)
{
end = index - 1;
index = Partition(numbers, nSize, start, end);
}
else
{
start = index + 1;
index = Partition(numbers, nSize, start, end);
}
}
int result = numbers[middle];
if(!CheckMoreThanHalf(numbers, nSize, result))
return 0;
return result;
}
bool CheckMoreThanHalf(vector<int>& numbers, int nSize, int number)
{
int time = 0;
for(int i = 0; i < nSize; i++)
{
if(numbers[i] == number)
time++;
}
return (time * 2 <= nSize) ? false : true;
}
int Partition(vector<int>& data, int length, int start, int end)
{
int index = length >> 1;
Swap(&data[index], &data[end]);
int small = start - 1;
for(index = start; index < end; index++)
{
if(data[index] < data[end])
{
++small;
if(small != index)
Swap(&data[index], &data[small]);
}
}
++small;
Swap(&data[end], &data[small]);
return small;
}
void Swap(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
};
时间复杂度O(n)的算法
#include<cstdlib>
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int nSize = numbers.size();
if(nSize == 0) return 0;
int number;
int count = 0;
for(int i = 0; i < nSize; i++)
{
if(count == 0)
{
count = 1;
number = numbers[i];
}
else
{
if(numbers[i] == number)
count++;
else
count--;
}
}
if(!CheckMoreThanHalf(numbers, nSize, number))
return 0;
return number;
}
bool CheckMoreThanHalf(vector<int>& numbers, int nSize, int number)
{
int time = 0;
for(int i = 0; i < nSize; i++)
{
if(numbers[i] == number)
time++;
}
return (time * 2 <= nSize) ? false : true;
}
};
空间复杂度为O(1)。