Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times.javascript
Note: The algorithm should run in linear time and in O(1) space.html
Example 1:java
Input: [3,2,3] Output: [3]
Example 2:数组
Input: [1,1,1,3,3,2,2,2] Output: [1,2]
找到数组中全部出现次数大于⌊ n/3 ⌋
的元素。app
限制时间为O(N)、空间为O(1),所以不能用Hash或者排序。使用 169. Majority Element (E) 中提到的摩尔投票法 Boyer-Moore Majority Vote。求全部出现次数大于⌊ n/3 ⌋
的元素,用反证法很容易证实这种元素最多只有两个,因此能够先用摩尔投票法得到两个候选元素,再从新遍历数组统计候选元素出现的次数,将知足条件的加入到结果集中。spa
class Solution { public List<Integer> majorityElement(int[] nums) { List<Integer> ans = new ArrayList<>(); int a = 0, b = 0; int countA = 0, countB = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == a) { countA++; } else if (nums[i] == b) { countB++; } else if (countA == 0) { a = nums[i]; countA = 1; } else if (countB == 0) { b = nums[i]; countB = 1; } else { countA--; countB--; } } countA = 0; countB = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == a) { countA++; } else if (nums[i] == b) { countB++; } } if (countA > nums.length / 3) { ans.add(a); } if (countB > nums.length / 3) { ans.add(b); } return ans; } }
/** * @param {number[]} nums * @return {number[]} */ var majorityElement = function (nums) { let ans = [] let a = 0, b = 0, countA = 0, countB = 0 for (let num of nums) { if (num === a) { countA++ } else if (num === b) { countB++ } else if (countA === 0) { a = num countA = 1 } else if (countB === 0) { b = num countB = 1 } else { countA-- countB-- } } countA = 0, countB = 0 for (let num of nums) { if (num === a) { countA++ } else if (num === b) { countB++ } } if (countA > Math.trunc(nums.length / 3)) ans.push(a) if (countB > Math.trunc(nums.length / 3)) ans.push(b) return ans }