多数元素

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

 

示例 1:

输入:nums = [3,2,3]
输出:3
示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2
 

提示:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109
 

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

 

 

分治解法:将数组分成左右两部分,分别求出左半部分的众数 a1 以及右半部分的众数 a2,随后在 a1 和 a2 中选出正确的众数

代码:

class Solution {
    int count_in_range(vector<int>&nums, int find, int left, int right){
        int c = 0;
        for(int i = left; i <= right; i++)
            if(nums[i] == find)
                ++c;
            
        
        return c;
    }
    int majority_element_rec(vector<int>&nums, int lo, int hi) {
        if (lo == hi)
            return nums[lo];
        int mid = (lo + hi) / 2;
        int left_majority = majority_element_rec(nums, lo, mid);
        int right_majority = majority_element_rec(nums, mid + 1, hi);
        if (count_in_range(nums, left_majority, lo, hi) > (hi - lo + 1) / 2)
            return left_majority;
        if (count_in_range(nums, right_majority, lo, hi) > (hi - lo + 1) / 2)
            return right_majority;
        return -1;
    }

public:
    int majorityElement(vector<int>& nums) {
        int me = majority_element_rec(nums, 0, nums.size()-1);
        return me;
    }
};

 注意穿参数vector<int>num时要加上&,不然会超时。

 

 

普通解法:

代码:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        map<int, int>m;
        int max = 0, maxn;
        for(int i=0; i<nums.size(); i++){
            m[nums.at(i)]++;
            if(m[nums.at(i)] > max){
                max = m[nums.at(i)];
                maxn = nums.at(i);
            }
        }
        return maxn;   
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

 

 

排序解法:

代码:

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

对数列进行排序时简化问题的一种手段 

 

摩尔投票算法:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int candidate = -1;
        int count = 0;
        for (int num : nums) {
            if (num == candidate)
                ++count;
            else if (--count < 0) {
                candidate = num;
                count = 1;
            }
        }
        return candidate;
    }
};

 

 

 

摩尔投票是一种用来解决绝对众数问题的算法。

在一个集合中,如果一个元素的出现次数比其他所有元素的出现次数之和还多,那么就称它为这个集合的绝对众数。等价地说,绝对众数的出现次数大于总元素数的一半

摩尔投票的过程非常简单,让我们把找到绝对众数的过程想象成一次选举。我们维护一个 m ,表示当前的候选人,然后维护一个 cnt 。对于每一张新的选票,如果它投给了当前的候选人,就把 cnt 加1,否则就把 cnt 减1(也许你可以想象成,B的一个狂热支持者去把A的一个支持者揍了一顿,然后两个人都没法投票)。特别地,计票时如果 cnt=0 ,我们可以认为目前谁都没有优势,所以新的选票投给谁,谁就成为新的候选人。

 

————— c++数组和vector的选择 ———————————

在对数据进行频繁访问执行操作时,数组比vector优秀很多。
但是,这不是说数组一定比vector好,vector拥有很多强大的功能,可以存储很多种类型,相比之下数组还是太单一了点,如果只是对一组数据进行简单的频繁访问执行操作,可以c++数组,否则大多数情况都还是使用c++的vector。

posted @ 2022-09-29 20:06  Yohoc  阅读(43)  评论(0编辑  收藏  举报