---
# System prepended metadata

title: Boyer-Moore majority vote algorithm

---

# Boyer-Moore majority vote algorithm

## Problem
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.  The algorithm should run in linear time and in O(1) space.

### Solution
決鬥法: 只有一個元素佔超過一半的量。遍歷陣列一次，把值和次數存起來，要是下一個元素值和目前的值不一樣，就把次數減1(殺死)，反之加1(累積)。要是次數等於0，就把值換成下一個元素。
Example:
array=[2,2,3,3,3,2,2,2,1]
決鬥過程:
value = 2 2 2 2 3 3 2 2 2
times = 1 2 1 0 1 0 1 2 1

經過一番廝殺後，存活下來的是2，因此答案為2。
原理: **要是有一個元素的量超過一半，那他一定承受得起這種消耗。**

```
// leetcode problem 169
int majorityElement(vector<int>& nums) {
    int ans=INT_MIN;
    int times=0;
    for(int i=0;i<nums.size();++i){
        if(times==0){
            ans=nums[i];
            times++;
        }else{
            if(nums[i]==ans){
                times++;
            }else{
                times--;
            }
        }
    }
    return ans;
}
```

## Extension Problem
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.

### Solution
一樣決鬥法，只是這次要決鬥出前兩多的元素，因為超過1/3的元素有可能有兩個，在這題裡面也可能沒有。因此要遍歷陣列兩次，第一次先決鬥，第二次統計這兩個元素的個數，如果超過n/3，就放入答案陣列。因為只需遍歷兩次和儲存兩個元素的值和個數，時間複雜度為2n=O(n)，空間複雜度為O(1)，符合題目需求，也絕對比排序或統計所有數字還快。

```
// leetcode problem 229
vector<int> majorityElement(vector<int>& nums) {
    vector<int> ans;
    long long v1=LLONG_MIN,v2=LLONG_MIN;
    int t1=0,t2=0;
    for(int i=0;i<nums.size();++i){
        if(v1==nums[i]){
            t1++;
            continue;
        }
        if(v2==nums[i]){
            t2++;
            continue;
        }

        if(t1==0){
            v1=nums[i];
            t1++;
            continue;
        }   
        if(t2==0){
            v2=nums[i];
            t2++;
            continue;
        }
        t1--;
        t2--; 
    }

    int c1=0,c2=0;
    for(int i=0;i<nums.size();++i){
        if(nums[i]==v1){
            c1++;
        }
        if(nums[i]==v2){
            c2++;
        }
    }
    if(c1>(int)nums.size()/3){
        ans.push_back(v1);
    }
    if(c2>(int)nums.size()/3){
        ans.push_back(v2);
    }


    return ans;
}
```






