229. Majority Element II
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.
本题主要是Boyer-Moore Majority Vote algorithm(具体参考:http://goo.gl/64Nams)的扩展。在找出现次数大于[n/2]的元素个数时,我们遍历两次数组,首先假设一个数为候选元素(candidate),以及与之对应的计数器count,用来统计candidate出现的次数,每次判断当前元素是否与candidate相等,如果相等则count++,否则count——,当count为0时,把当前元素设为候选元素。
candidate = 0 count = 0 for value in input: if count == 0: candidate = value if candidate == value: count += 1 else: count -= 1
本题是找大于出现次数大于[n/3]的元素个数,显然这样的元素最多只有两个。于是我们便可以参考以上的思想,设置两个count和candidate。我们依然遍历两次数组。
class Solution { public: vector<int> majorityElement(vector<int>& nums) { vector<int>ans; int count1=0,count2=0,candidate1=0,candidate2=1; for(int n: nums){ if(n==candidate1)count1++; else if(n==candidate2)count2++; else if(count1==0){ candidate1=n; count1=1; } else if(count2==0){ candidate2=n; count2=1; } else { count1--; count2--; } } count1=count2=0; for(int n: nums){ if(n==candidate1)count1++; else if(n==candidate2)count2++; } if(count1>nums.size()/3)ans.push_back(candidate1); if(count2>nums.size()/3)ans.push_back(candidate2); return ans; } };
再扩展下,如果要找出现的次数大于[n/k]的元素的个数,我们就设置k-1个计数器和k-1个候选元素。
public class Solution { public List<Integer> majorityElement(int[] nums) { int n = nums.length, k = 3; //in this question, k=3 specifically List<Integer> result = new ArrayList<Integer>(); if (n==0 || k<2) return result; int[] candidates = new int[k-1]; int[] counts = new int[k-1]; for (int num: nums) { boolean settled = false; for (int i=0; i<k-1; i++) { if (candidates[i]==num) { counts[i]++; settled = true; break; } } if (settled) continue; for (int i=0; i<k-1; i++) { if (counts[i]==0) { counts[i] = 1; candidates[i] = num; settled = true; break; } } if (settled) continue; for (int i=0; i<k-1; i++) counts[i] = (counts[i] > 0) ? (counts[i]-1) : 0; } Arrays.fill(counts, 0); for (int num: nums) { for (int i=0;i<k-1; i++) { if (candidates[i]==num) { counts[i]++; break; } } } for (int i=0; i<k-1; i++) if (counts[i]>n/k) result.add(candidates[i]); return result; } }