Leetcode 169. Majority Element

Leetcode
169. Majority Element
 Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
 You may assume that the array is non-empty and the majority element always exist in the array.
  
解法一:
  暴力,两个循环;时间复杂度O(n^2),空间复杂度O(1)。
  
解法二:
  先排序,因为结果一定存在,直接返回排序后的数组中间值;时间复杂度O(n log n),空间复杂度O(1)。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums[nums.size() / 2];
    }
};

 
解法三:
  朴素的分治思想,将一个数组平均分为两部分A和B,求A和B的多数元素(Majority Element),所以原数组中的多数只可能出现在A和B的多数两个之中(若不然,假设存在一个数不是A和B的多数中的任意一个,则它在数组中出现的次数大于A和B的多数出现的次数),对两个候选的多数,在原数组中一遍遍历,统计次数,便可以得到原数组的多数。
  时间复杂度O(n log n),空间复杂度O(1)。
  
解法四:多数投票算法(Moore majority vote algorithm)
  该算法在其局部变量中维护一个序列元素和一个计数器,计数器最初为零。然后它会逐个处理序列的元素。当处理元素x时,如果计数器为零,则算法将x存储为其记忆的序列元素并将计数器设置为1。否则,它会将x与存储的元素进行比较,然后递增计数器(如果它们相等)或递减计数器(否则)。在这个过程结束时,如果序列有大多数,它将是算法存储的元素。
  时间复杂度O(n),空间复杂度O(1)。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int candidate = 0;
        int count = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (candidate == nums[i]) {
                ++count;
            } else {
                if (count == 0) {
                    candidate = nums[i];
                } else {
                    --count;
                }
            }
        }

        return candidate;
    }
};

正确性验证:
  一、若多数元素在数组中的排列顺序刚好可以让它一直维持candidate的身份(即:不会在以数组第一个元素为开头的某个子序列中,多数元素出现的次数不大于子序列长度的一半),则到最后,candidate就是多数元素;
  二、若多数元素在以数组第一个元素为开头的某个子序列中,不能够维持出现的次数一值大于子序列长度的一半,则candidate会一直在变(因为其他的元素无法一直维持它的candidate身份),排除掉其余所有无法满足条件的元素,剩下来的便是满足条件的多数元素了(假设多数元素存在的前提下)。
缺陷(不针对这一题):当多数元素不存在时,该算法依然会给出一个结果(最后一个candidate)。
针对上诉缺陷的改进:将算法取得的candidate,用原数组遍历一遍,看是否是多数元素。
优点:该算法支持分治,从而能够并行,可以将数组分为两部分,分别求出两部分的candidate和各自的count,根据两个candidate的count值,可以得到原数组的多数元素。

1 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm

猜你喜欢

转载自blog.csdn.net/m0_37600543/article/details/79994481
今日推荐