leetcode:169. 多数元素

题目来源

  • leetcode:169. 多数元素

题目描述

leetcode:169. 多数元素_第1张图片

题目解析

摩根投票法

候选人(major)初始化为num[0],票数count初始化为1
当遇到与major相同的数,则票数count = count + 1,否则count = count - 1;
当遇到count == 0时,更好候选人major,并将票数count重置为1

  • cpp:
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int major = nums[0];
        int count = 1;

        for (int i = 1; i < nums.size(); ++i) {
            if(count == 0){
                major = nums[i];
                count = 1;
            }else{
                if(nums[i] == major){
                    count++;
                }else{
                    count--;
                }
            }
        }

        return major;
    }
};

投票算法证明:

  • 如果候选人不是maj 则 maj,会和其他非候选人一起反对 会反对候选人,所以候选人一定会下台(maj==0时发生换届选举)
  • 如果候选人是maj , 则maj 会支持自己,其他候选人会反对,同样因为maj 票数超过一半,所以maj 一定会成功当选

排序

  • 由于众数出现的频率大于n/2,所以在排序之后众数必存在于下标[n/2]处(本题默认数组中是一定存在众数的,所以返回下标[n/2]可行)
    leetcode:169. 多数元素_第2张图片
int majorityElement(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    return nums[nums.size() / 2];
}

在这里插入图片描述

哈希表

使用hash映射来存储每个元素以及出现的次数。对于哈希映射中的每个键值对,键表示一个元素,值表示该元素出现的次数。

我们同样也可以在遍历数组 nums 时候使用打擂台的方法,维护最大的值,这样省去了最后对哈希映射的遍历。

class Solution {
public:
    #include 
    int majorityElement(vector<int>& nums) {
        std::unordered_map<int, int> counts;
        int majority = 0, count = 0;
        for(int num : nums){
            ++counts[num];
            if(counts[num] > count){
                majority = num;
                count = counts[num];
            }
        }

        return majority;
    }
};

leetcode:169. 多数元素_第3张图片

随机法

leetcode:169. 多数元素_第4张图片

class Solution {
    // 生成一个随机坐标
    private static int randomIndex(Random rand, int low, int high){
        return rand.nextInt(high - low) + low;
    }

    // 统计当前元素出现的次数
    public static int countElement(int[] arr, int index){
        int count = 0;
        for (int i = 0; i < arr.length; i++){
            if (arr[i] == arr[index]){
                count++;
            }
        }
        return count;
    }

    public  int majorityElement(int[] nums) {
        Random rand = new Random();

        int m = nums.length / 2;
        while (true){
            int index = randomIndex(rand, 0, nums.length);
            int count = countElement(nums, index);
            if (count > m){
                return nums[index];
            }
        }
    }
}

在这里插入图片描述
leetcode:169. 多数元素_第5张图片

类似题目

题目 思路
leetcode:169. 无序数组中的多数元素(超过n/2) majority-element 这里已经确保了主要元素一定存在,所以最后不需要验证
面试题 17.10. 无序数组中的主要元素(超过n/2) find-majority-element-lcci 没有说主要元素一定存在,所以最后需要看major是否是主要元素
leetcode:229. 无序数组中的多数元素 II(超过n/3) majority-element ii
leetcode:1287. 有序数组中出现次数超过25%的元素

你可能感兴趣的:(算法与数据结构,leetcode,算法,java)