题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
解题思路
出现超过一半的数,一定是排好序的数组的中位数,即位置为 n/2 的数。
找到这个中位数,然后,遍历一次,判断是否出现次数超过一半,若是,则返回true,否则,没有这样的数。
关键在于如何得到这个中位数?
两种思路,
1、对数组进行排序,直接取中位数,时间复杂度O(nlogn);
2、利用快排的partition算法,得到位置为n/2的数,即中位数,时间复杂度O(n);
实现代码
<span style="font-size:18px;">//O(nlogn)解法
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int result=0;
if(numbers.empty())
return 0;
sort(numbers.begin(),numbers.end());
int len = numbers.size();
int num = numbers[len/2];
int count = 0;
for(int i=0;i<len;i++)
{
if(numbers[i] == num)
count++;
}
if(count > len/2)
{
result = num;
return result;
}
else
return 0;
}
};
//O(n)解法
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int result=0;
if(numbers.empty())
return 0;
//sort(numbers.begin(),numbers.end());
int len = numbers.size();
int mid = len >> 1;
int start = 0;
int end = len-1;
int index = partition(numbers,start, end);
while(index != mid)
{
if(index > mid)
{
end = index-1;
index = partition(numbers,start,end);
}
else
{
start = index+1;
index = partition(numbers,start,end);
}
}
int num = numbers[index];
int count = 0;
for(int i=0;i<len;i++)
{
if(numbers[i] == num)
count++;
}
if(count > len/2)
{
result = num;
return result;
}
else
return 0;
}
int partition(vector<int> numbers, int low, int high)
{
int pivotloc = low;
int temp = numbers[low];
while(low < high)
{
while(low < high && numbers[high] >= temp)
high--;
if(low < high)
{
numbers[low] = numbers[high];
low++;
}
while(low < high && numbers[low] <= temp)
low++;
if(low < high)
{
numbers[high] = numbers[low];
high--;
}
}
numbers[low] = temp;
return low;
}
};
</span>