[leetcode] 229. Majority Element II 解题报告

来源:互联网 发布:阿里云新手礼包在哪里 编辑:程序博客网 时间:2024/05/22 06:27

题目链接:https://leetcode.com/problems/majority-element-ii/

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  1. How many majority elements could it possibly have?
  2. Do you have a better hint? Suggest it!

思路:这道题目有两种解法,第一种是基本快速排序。在快速排序中有个partition函数可以将数组两部分,左边是比这个数小的数,右边是比这个值大的数。

在这题中我们要找到出现次数超过1/3的数,那么这个数最多有两个,利用partition找出应该出现在数组1/3处,和2/3处的值,则出现超过1/3的数必然在这两个数中。然后再验证这两个数是不是解。这种解法期望的时间复杂度是O(n),但是在最坏情况下依然是O(n^2)。

还有另外一种解法是BM投票算法(Boyer-Moore Majority Vote algorithm),这种算法是设置一个数的计数器,在遍历数组的时候,如果是这个数,则计算器加一,不是则减一,用来计数超过一半的数非常方便。在这里我们需要进行改进一下,设置两个计数器,来统计两个数出现的次数。

如果是这两个数中的一个,则他的计算器加1,如果不是这两个数中的任何一个,则计算器都减1,如果计数器为0了,则统计当前的这个数。那么如果一个数出现次数超过1/3,则最后必然出现在统计的数中,但是我们不能确定现在得到的这两个数出现次数是否超过1/3,因此最后需要再验证一下。

代码如下:

class Solution {public:    vector<int> majorityElement(vector<int>& nums) {        if(nums.size()==0) return {};        int num1, num2, cnt1=0, cnt2=0,len=nums.size();        for(auto val: nums)        {            if(num1 == val) cnt1++;            else if(num2 == val) cnt2++;            else if(cnt1==0) cnt1 = 1, num1 = val;            else if(cnt2==0) cnt2 = 1, num2 = val;            else cnt1--, cnt2--;        }        cnt1 = 0, cnt2 = 0;        for(auto val: nums)            if(val == num1) cnt1++;            else if(val == num2) cnt2++;        vector<int> ans;        if(cnt1 > len/3.0) ans.push_back(num1);        if(cnt2 > len/3.0) ans.push_back(num2);        return ans;    }};


0 0