题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路详解
思路1---寻找中位数(会改变原数组的顺序)
1. 先整体排序,找到中位数
(1)先对数组进行排序,如果某个数字m的出现次数超过数组长度的一半,那么排序之后的数组的中间元素一定是该数字m
(2)获得排序之后的数组的中间元素value = numbers[size/2]
(3)统计该数字出现的次数是否大于数组长度的一半
为了减少遍历次数,可以从中间向两边遍历,计数value出现的次数
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int s = numbers.size();
if(s == 0)
return 0;
sort(numbers.begin(), numbers.end());
int value = numbers[s / 2];
int cnt = 0;
int i = 0;
for(i = 0; i < s; i++)
{
if(numbers[i] == value)
break;
}
while(i < s)
{
if(numbers[i] != value)
break;
cnt++;
i++;
}
if(cnt > (s/2))
return value;
else
return 0;
}
};
2. 利用快速排序思想找到中位数
(会改变原数组的顺序)
---寻找数组的中位数
出现次数超过数组长度的一半的数字一定是数组的中位数,利用快速排序的思想:
(1)在数组中随机找一个数,将小于它的数放在他的左边,大于它的数放在他的右边
(2)如果这个数的下标刚好是size/2,那么他就是数组的中位数
(3)否则,如果他的下标<size/2,中位数在它的右边,>size/2中位数在它的左边
(4)递归在它的左边或右边部分进行查找
---判断中位数的出现次数是否大于数组长度的一半
遍历一遍数组,统计中位数的出现次数,判断是否超过长度的一半
思路2--- 数组的特点之次数和
(不改变原数组的顺序)
出现次数超过数组长度的一半,说明它出现的次数比数组中所有元素出现的次数和还要多
因此可以在遍历的时候保存两个值,一个是数组中的数字value,一个是次数
(1)与前一个数字相同时,times++
(2)与前一个数字不同时,times--
(3)当times为0时,value重新赋值为当前的元素,并将times设置为1