线性时间多数投票算法

81 阅读1分钟

线性时间多数投票算法

论文链接: www.cs.utexas.edu/~moore/best…

问题描述

给定一个数组,其中有一个元素出现的次数超过了数组长度的一半,找出这个元素——多数元素。

注意:

  1. 假设数组长度为n, 那么长度的一半为n/2向下取整
  2. 假设数组中始终存在多数元素

算法描述

  1. 初始化候选元素candidateNone, 候选元素出现的次数count为0
  2. 遍历数组中的每个元素x
    1. 如果count为0, 则将x赋值给candidate, 并将count置为1
    2. 如果x等于candidate, 则count加1, 否则count减1
  3. 返回candidate

图示

维护一个candidate:count的结构, 遍历数组.

在这里插入图片描述

初始化candidateNone, count为0


在这里插入图片描述 前进一步, candidateA, count为1


在这里插入图片描述

前进一步, candidateA, count为2


在这里插入图片描述

前进一步, candidateA, count为3


在这里插入图片描述

前进一步, 遇到C, candidateA, count减一为2


在这里插入图片描述

前进一步, candidateC, count减一为1


在这里插入图片描述

前进一步, count减一为0, 所以candidate变为None


在这里插入图片描述

candidateB, count为1


在这里插入图片描述

candidateNone, count为0


在这里插入图片描述

candidateC, count为1


在这里插入图片描述

candidateC, count为2


在这里插入图片描述

candidateC, count为1


在这里插入图片描述

candidateC, count为2


最后返回C

代码

C++

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

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

        return candidate;
    }
};

Go

func majorityElement(nums []int) int {
    major := nums[0]
    count := 1

    for _, num := range nums[1:] {
        if num == major {
            count++
        } else if count == 0 {
            major = num
            count++
        } else {
            count--
        } 
    }

    return major
}