摩尔投票算法(Boyer–Moore majority vote algorithm)

原创 2016年08月30日 15:50:56

问题描述:

1. The majority vote problem is to determine in any given sequence of choices whether there is a choice with more occurrences than half of the total number of choices in the sequence and if so, to determine this choice. Note how this definition contrasts with the mode in which it is not simply the choice with the most occurrences, but the number of occurrences relative to the total length of the sequence. Mathematically, given a finite sequence (length n) of numbers, the object is to find the majority number defined as the number that appears more than ⌊ n/2 ⌋ times.

2. Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.


算法描述:

The algorithm is carried out in two steps:

  1. Eliminate all elements except one.
    Iterating through the array of numbers, maintain a current candidate and a counter initialized to 0. With the current element x in iteration, update the counter and (possibly) the candidate: if the counter is 0, set the current candidate to x and the counter to 1. If the counter is not 0, increment or decrement the counter based on whether x is the current candidate.
  2. Determine if the remaining element is a valid majority element.
    With the candidate acquired in step 1, iterate through the array of numbers and count its occurrences. Determine if the result is more than half of the sequence's length. If so, the candidate is the majority. Otherwise, the sequence doesn't contain a majority.

Note that the counter can be a maximum of {\displaystyle n}n which requires {\displaystyle O(\log n)}O(\log n) space. In practice, however, a constant number of bits should suffice as a {\displaystyle 128}{\displaystyle 128} bit counter can go upto {\displaystyle 2^{128}}2^{128} which is large enough for any practical computation. The time complexity remains {\displaystyle O(n)}O(n), even considering the amount of time it takes to increment the counter because it can be incremented in constant amortized time.

算法实现:

1. Given a finite sequence (length n) of numbers, the object is to find the majority number defined as the number that appears more than ⌊ n/2 ⌋ times. 

import java.util.*;
public class MajorityVote {
    public int majorityElement(int[] num) {
        int n = num.length;
        int candidate = num[0], counter = 0;
        for (int i : num) {
            if (counter == 0) {
                candidate = i;
                counter = 1;
            } else if (candidate == i) {
                counter++;
            } else {
                counter--;
            }
        }

        counter = 0;
        for (int i : num) {
            if (i == candidate) counter++;
        }
        if (counter <= n / 2) return -1;
        return candidate;

    }
    public static void main(String[] args) {
        MajorityVote s = new MajorityVote();
        System.out.format("%d\n", s.majorityElement(new int[] {1, 2, 3}));
        System.out.format("%d\n", s.majorityElement(new int[] {2, 2, 3}));
    }
}


2. Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

分析:
因为要找出的是出现次数大于⌊ n/3 ⌋的元素,因此最多只可能存在两个这样的元素,而且要求O(1)的空间复杂度,因此只能使用摩尔投票法。首先我们遍历一遍数组找出两个候选元素,接着再遍历一遍数组,判断候选元素的出现次数是否超过三分之一即可。我们如何确定两个候选元素呢?当有候选元素未设置时,先将当前遍历到的元素设置为候选元素。若遍历到的元素和其中一个候选元素相等时,候选元素的计数器加一,若和两个候选元素都不相等,则两个候选元素的计数器都减一。
其实摩尔投票法的本质就是将元素进行分组,每组中都是不同的元素,最后剩下的那些元素就可能是出现次数最多的元素。例如上文中的解法就是将所有元素分成若干个三元组,每组中的数字都是各不相同的。如果一个元素出现的次数超过了三分之一,那么它必然在剩下的元组中存在,因此它能成为候选元素。

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int num1 = 0, num2 = 1;
        int count1 = 0, count2 = 0;
        for(int num: nums) {
            if (count1 == 0) {
                num1 = num;
                count1 = 1;
            } else if (num1 == num) {
                count1 ++;
            } else if (count2 == 0) {
                num2 = num;
                count2 = 1;
            } else if (num2 == num) {
                count2 ++;
            } else {
                count1 --;
                count2 --;
                if (count1 == 0 && count2 > 0) {
                    num1 = num2;
                    count1 = count2;
                    num2 = 0;
                    count2 = 0;
                }
            }
        }
        if (count1 > 0) {
            count1 = 0;
            for(int num: nums) if (num1 == num) count1 ++;
        }
        if (count2 > 0) {
            count2 = 0;
            for(int num: nums) if (num2 == num) count2 ++;
        }
        List<Integer> results = new ArrayList<>();
        if (count1*3>nums.length) results.add(num1);
        if (count2*3>nums.length) results.add(num2);
        return results;
    }
}

Reference:

1. https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm

2. Moore的主页上有这个算法的介绍:A Linear Time Majority Vote Algorithm 和 这个算法的一个简单示例演示,链接如下:

http://www.cs.utexas.edu/~moore/best-ideas/mjrty/index.html

3. https://leetcode.com/problems/majority-element-ii/

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Leetcode 之 Majority Element I-- HashMap法以及 摩尔投票法

Leetcode 之Majority Element I

229.Majority Element II

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algori...

摩尔投票法, O(n) O(1) 求出现次数大于n/2,n/3次数的数

参考 摩尔投票法讲解 http://www.cnblogs.com/grandyang/p/4606822.html 向上取整和向下取整。 http://blog.sina.com.cn/s...

[Leetcode] Week Two & Three ------ Array

对于Leetcode中部分数组题目比较基本的个人解析。

Leetcode Majority Element系列 摩尔投票法

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit...

Boyer–Moore majority vote algorithm

思想来自维基百科 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithmLeetCode 中有这样一题: ...

LeetCode 229 Majority Element II(主要元素II)(Array)(Boyer–Moore majority vote algorithm)

原文给定一个长度为n的整型数组,找出所有出现超过 ⌊ n/3 ⌋ 次的元素。算法应该运行在线性时间上,且进用O(1)O(1)空间。提示:它可能有多少个主要元素?原文Given an integer a...
  • NoMasp
  • NoMasp
  • 2016-08-29 21:40
  • 1312

Boyer-Moore Majority Vote Algorithm的更一般性问题

1) 问题描述基本问题:对于一个给定数组A[0:n-1],找出出现次数大于⌊n/2⌋\lfloor n/2\rfloor 的元素,称为Majority element. 一般问题:对于一个给定数组A...
  • isunn
  • isunn
  • 2016-02-25 11:32
  • 633

多数投票算法 Majority Vote Algorithm

题目如下: Write a program to find the element in an array that is repeated more than half number of time...

多数投票算法(Majority Vote Algorithm)

假设有一个字符串数组,其中含有N个元素,qi
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)