Divide and Conquer:169. Majority Element

来源:互联网 发布:云计算系统 编辑:程序博客网 时间:2024/06/06 01:50

这是到求众数的问题,有很多种解法,其中我感觉比较好的有两种,一种是用哈希表,这种方法需要O(n)的时间和空间,另一种是用一种叫摩尔投票法 Moore Voting,需要O(n)的时间和O(1)的空间,比前一种方法更好。这种投票法先将第一个数字假设为众数,然后把计数器设为1,比较下一个数和此数是否相等,若相等则计数器加一,反之减一。然后看此时计数器的值,若为零,则将当前值设为候选众数。以此类推直到遍历完整个数组,当前候选众数即为该数组的众数。

class Solution {public:    int majorityElement(vector<int>& nums) {        int res = 0, cnt = 0;        for (int num : nums) {            if (cnt == 0) {                res = num;                 ++cnt;            }            else (num == res) ? ++cnt : --cnt;        }        return res;    }};

这道题的提示是使用分治法或位操作来求解。将数组分成两部分,寻找第一个部分中出现次数超过一半的元素为A,第二个部分出现次数超过一半的元素为B,如果A==B,那么A就是这个数组中出现次数超过一半的元素,如果A!=B,那么A和B都可能是这个数组中出现次数超过一半的元素,那么重新遍历这个数组,记录A和B出现的次数,返回出现次数多的元素,时间复杂度T(n)=2T(n/2)+2n=O(nlogn)。

class Solution {public:    int majorityElement(vector<int>& nums) {        return majority(nums, 0, nums.size() - 1);    }private:    int majority(vector<int>& nums, int left, int right) {        if (left == right) return nums[left];        int mid = left + ((right - left) >> 1);        int lm = majority(nums, left, mid);        int rm = majority(nums, mid + 1, right);        if (lm == rm) return lm;        return count(nums.begin() + left, nums.begin() + right + 1, lm) > count(nums.begin() + left, nums.begin() + right + 1, rm) ? lm : rm;    }};