题目:给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入:[3,2,3]
输出:3
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
解答如下:
简单的方法不多说,无非是用数组来以空间换时间,数组下标为输入的值,数组的值为当前数字(即数组下标)出现的个数。这种方法及其容易想到,但是耗费空间比较大,而且我们未必知道输入的数组中最大的数是多少,若是数字过于分散,则会造成很大的空间浪费,所以我们一般不会去采用这样的方法。接下来我要说的是一种非常简单的方法,时间复杂度为O(n),空间复杂度为O(1)。
在解决这个问题前我们需要介绍一下摩尔投票算法,解答这个问题正是应用到这个方法。
Boyer-Moore majority vote algorithm(摩尔投票算法)是一种线性时间复杂度和常数级空间复杂度的算法,用来查找元素序列中的众数。
该算法定义了两个变量:一个是目前出现次数最多的数num,一个是计数器count,计数器初值为零。 然后我们遍历序列中的每个元素。如果count==0,则num=x;count=1;(其中x表示我们遍历到的元素)。 如果num==x,那么count++,否则count--。 最后返回m即可。
回到我们的题目当中:
首先可以将num赋值为0,count必须为0。碰到数组的第一个值(即count为0时),要将该值赋给num(此时它出现的次数最多),count值=1,若下一个数字一样,则count++(说明当前值出现次数多了一次),若不一样,则count--,若count=0,则令num=x(即说明,只有count不为0,num代表的值就是当前出现次数最多的值)
代码实现如下所示:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int len=nums.size();
if(len<=0) return 0;
int num=0,count=0;
for(int i=0;i<len;i++){
if(count==0){
num=nums[i];
}
if(num==nums[i]){
count++;
}
if(num!=nums[i]){
count--;
}
}
return num;
}
};
网友评论