0
点赞
收藏
分享

微信扫一扫

使用 RestHighLevelClient 进行 Elasticsearch 高亮查询及解析

流沙雨帘 2024-08-14 阅读 27

概述

摩尔投票是在一次遍历、常量空间下求数组多数元素的算法,先来看这道题

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

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

示例 1:

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

示例 2:

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

思路

*注意*:如果数组中某个数存在出现次数占数组的一半以上,我们称之为众数(这与数学定义不同)

想想这样一个事:

数组中某个数存在出现次数占数组的一半以上,那么它与其他的非众数一一抵消,肯定还会剩至少一个众数没被抵消。 

那如果非众数内部也相互抵消呢?那剩的众数就更多了。

算法过程

 我们有一个衡量标准votes,初始值为0,又有众数x,表示当前认为的众数是x。

*注意*:x不一定是全局众数,它只代表遍历到此位置时我们对众数的推断。

如果votes==0,那说明前面的数全抵消掉了,那么让x得到当前遍历位置的值。

如果当前的元素==x,votes+1,否则-1,这是在模拟抵消的过程。

x的最终值就是众数。

因为:数组中某个数存在出现次数占数组的一半以上,那么它与其他的非众数一一抵消,肯定还会剩至少一个众数没被抵消。 

我们为什么可以在不完全遍历时推断众数呢?

因为:如果非众数内部也相互抵消,那剩的众数就更多了。我们选取局部假众数实际就是在进行这个过程。

例如,

nums[i] 1 2 2 3 4 4 4 4 4 5 4
     i  0 1 2 3 4 5 6 7 8 9 10

一开始认为1是众数,1被抵消后认为2是众数,2被抵消后认为4是众数,在这个过程发生的有:

真众数与所有非真众数抵消,假众数与前面的数抵消。

理想情况下只有真众数与其他数抵消,它尚能剩余,更何况其他数之间的内部抵消也存在。

Code

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int x,votes=0;
        for(const int& i:nums){
            if(votes==0)x=i;
            votes+=(i==x?1:-1);
        }
        return x;
    }
};
举报

相关推荐

0 条评论