# 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; } ```