Boyer-Moore Majority Vote Algorithm
简介
- 该算法目的是找出数组中数目大于数组中元素总数 [n/2] [ n / 2 ] 的元素(如果存在的话),相对于排序再查找的方法,该算法的时间复杂度是 O(N) O ( N ) ,空间复杂度为 O(1) O ( 1 ) 。
- 该算法的主要思想是,要查找的元素的个数肯定比剩下的元素个数都要多,因此首先轮询数组,设置目标元素的初始值为 goal=a[0] g o a l = a [ 0 ] ,使用一个cnt变量进行计数,如果找到相等元素, cnt++ c n t + + ,否则 cnt−− c n t − − ,如果 cnt=0 c n t = 0 ,则将当前的元素赋值给目标元素,最终得到 goal g o a l 。然后第二次轮询数组,找出goal的个数,如果其个数确实大于 [n/2] [ n / 2 ] ,则找到该元素,否则不存在符合条件的元素。
- 参考链接:http://www.cs.rug.nl/~wim/pub/whh348.pdf
扩展
- 如果找出数目大于 [n/3] [ n / 3 ] 的元素,思路也是类似,记录两个值,依次轮询,找到两个数,最后判断两个数是否相等以及两个数的个数是否满足要求即可。
- 题目链接:https://leetcode.com/problems/majority-element-ii/description/
代码
#include <vector> #include <iostream> #include <algorithm> #include <sstream> using namespace std; // 使用了Boyer-Moore Majority Vote algorithm算法的变形 // 找出数目最多的元素,使用2次轮询即可完成 class Solution229 { public: vector<int> majorityElement(vector<int>& nums) { vector<int> ret; if (nums.empty()) return ret; int cnt1 = 0, cnt2 = 0; int num1 = nums[0], num2 = nums[0]; for (int i = 0; i < nums.size(); i++) { if (nums[i] == num1) cnt1++; else if (nums[i] == num2) cnt2++; else if (cnt1 == 0) { num1 = nums[i]; cnt1 = 1; } else if (cnt2 == 0) { num2 = nums[i]; cnt2 = 1; } else { cnt1--; cnt2--; } } cnt1 = 0; cnt2 = 0; for (int i = 0; i < nums.size(); i++) { if (nums[i] == num1) cnt1++; if (nums[i] == num2) cnt2++; } if (cnt1 > nums.size() / 3) ret.push_back( num1 ); if (cnt2 > nums.size() / 3 && num2 != num1) ret.push_back( num2 ); return ret; } }; int main() { Solution229 s; vector<int> nums = { 1,1 }; vector<int> ret = s.majorityElement( nums ); cout << endl; system("pause"); return 0; }