题目
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.
Note: The algorithm should run in linear time and in O(1) space.
Example 1:
Input: [3,2,3]Output: [3]
Example 2:
Input: [1,1,1,3,3,2,2,2]Output: [1,2]
题意
找到数组中所有出现次数大于⌊ n/3 ⌋的元素。
思路
限制时间为O(N)、空间为O(1),因此不能用Hash或者排序。使用 0169. Majority Element (E) 中提到的摩尔投票法 Boyer-Moore Majority Vote。求所有出现次数大于⌊ n/3 ⌋的元素,用反证法很容易证明这种元素最多只有两个,所以可以先用摩尔投票法获得两个候选元素,再重新遍历数组统计候选元素出现的次数,将满足条件的加入到结果集中。
代码实现
Java
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;}}
JavaScript
/*** @param {number[]} nums* @return {number[]}*/var majorityElement = function (nums) {let ans = []let a = 0, b = 0, countA = 0, countB = 0for (let num of nums) {if (num === a) {countA++} else if (num === b) {countB++} else if (countA === 0) {a = numcountA = 1} else if (countB === 0) {b = numcountB = 1} else {countA--countB--}}countA = 0, countB = 0for (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}
