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]

169. Majority Element 的拓展,这题要求的是出现次数大于n/3的元素,并且限定了时间和空间复杂度,因此不能排序,不能使用哈希表。

解法:Boyer-Moore多数投票算法 Boyer–Moore majority vote algorithm,T:O(n)  S: O(1) 摩尔投票法 Moore Voting

Java:

public List<Integer> majorityElement(int[] nums) {
if (nums == null || nums.length == 0)
return new ArrayList<Integer>();
List<Integer> result = new ArrayList<Integer>();
int number1 = nums[0], number2 = nums[0], count1 = 0, count2 = 0, len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
else if (count1 == 0) {
number1 = nums[i];
count1 = 1;
} else if (count2 == 0) {
number2 = nums[i];
count2 = 1;
} else {
count1--;
count2--;
}
}
count1 = 0;
count2 = 0;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
}
if (count1 > len / 3)
result.add(number1);
if (count2 > len / 3)
result.add(number2);
return result;
}  

Python:

class Solution:
# @param {integer[]} nums
# @return {integer[]}
def majorityElement(self, nums):
if not nums:
return []
count1, count2, candidate1, candidate2 = 0, 0, 0, 1
for n in nums:
if n == candidate1:
count1 += 1
elif n == candidate2:
count2 += 1
elif count1 == 0:
candidate1, count1 = n, 1
elif count2 == 0:
candidate2, count2 = n, 1
else:
count1, count2 = count1 - 1, count2 - 1
return [n for n in (candidate1, candidate2)
if nums.count(n) > len(nums) // 3]

Python:

class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
k, n, cnts = 3, len(nums), collections.defaultdict(int) for i in nums:
cnts[i] += 1
# Detecting k items in cnts, at least one of them must have exactly
# one in it. We will discard those k items by one for each.
# This action keeps the same mojority numbers in the remaining numbers.
# Because if x / n > 1 / k is true, then (x - 1) / (n - k) > 1 / k is also true.
if len(cnts) == k:
for j in cnts.keys():
cnts[j] -= 1
if cnts[j] == 0:
del cnts[j] # Resets cnts for the following counting.
for i in cnts.keys():
cnts[i] = 0 # Counts the occurrence of each candidate integer.
for i in nums:
if i in cnts:
cnts[i] += 1 # Selects the integer which occurs > [n / k] times.
result = []
for i in cnts.keys():
if cnts[i] > n / k:
result.append(i) return result def majorityElement2(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
return [i[0] for i in collections.Counter(nums).items() if i[1] > len(nums) / 3]  

C++:

class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> res;
int m = 0, n = 0, cm = 0, cn = 0;
for (auto &a : nums) {
if (a == m) ++cm;
else if (a ==n) ++cn;
else if (cm == 0) m = a, cm = 1;
else if (cn == 0) n = a, cn = 1;
else --cm, --cn;
}
cm = cn = 0;
for (auto &a : nums) {
if (a == m) ++cm;
else if (a == n) ++cn;
}
if (cm > nums.size() / 3) res.push_back(m);
if (cn > nums.size() / 3) res.push_back(n);
return res;
}
};

C++:

vector<int> majorityElement(vector<int>& nums) {
int cnt1 = 0, cnt2 = 0, a=0, b=1; for(auto n: nums){
if (a==n){
cnt1++;
}
else if (b==n){
cnt2++;
}
else if (cnt1==0){
a = n;
cnt1 = 1;
}
else if (cnt2 == 0){
b = n;
cnt2 = 1;
}
else{
cnt1--;
cnt2--;
}
} cnt1 = cnt2 = 0;
for(auto n: nums){
if (n==a) cnt1++;
else if (n==b) cnt2++;
} vector<int> res;
if (cnt1 > nums.size()/3) res.push_back(a);
if (cnt2 > nums.size()/3) res.push_back(b);
return res;
}

  

  

类似题目:

[LeetCode] 169. Majority Element 多数元素

  

All LeetCode Questions List 题目汇总

04-29 23:25