题目:
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.
Hint:
How many majority elements could it possibly have?
题解:
根据提示可以算出,最多有两个元素可以满足条件。在Majority Element I的基础上改进。不知道如何证明算法的正确性。
C++版:
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> result;
if(nums.size() == 0)
return result;
if(nums.size() == 1)
return nums;
int c1 = 0, c2 = 0, count1 = 0, count2 = 0;
for(int i = 0; i < nums.size(); i++) {
if(nums[i] == c1)
count1++;
else if(nums[i] == c2)
count2++;
else {
count1--;
count2--;
}
if(count1 < 0) {
c1 = nums[i];
count1 = 1;
} else if(count2 < 0) {
c2 = nums[i];
count2 = 1;
}
}
count1 = 0;
count2 = 0;
for(int i = 0; i < nums.size(); i++) {
if(nums[i] == c1)
count1++;
else if(nums[i] == c2)
count2++;
}
if(count1 > nums.size() / 3)
result.push_back(c1);
if(count2 > nums.size() / 3)
result.push_back(c2);
return result;
}
};
Java版:
public class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> result = new ArrayList<>();
if(nums.length == 0)
return result;
if(nums.length == 1) {
result.add(nums[0]);
return result;
}
int c1 = 0, c2 = 0, count1 = 0, count2 = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == c1) {
count1++;
} else if(nums[i] == c2) {
count2++;
} else {
count1--;
count2--;
}
if(count1 < 0) {
c1 = nums[i];
count1 = 1;
} else if(count2 < 0) {
c2 = nums[i];
count2 = 1;
}
}
count1 = 0;
count2 = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == c1)
count1++;
else if(nums[i] == c2)
count2++;
}
if(count1 > nums.length / 3)
result.add(c1);
if(count2 > nums.length / 3)
result.add(c2);
return result;
}
}
Python版:
class Solution:
# @param {integer[]} nums
# @return {integer[]}
def majorityElement(self, nums):
if len(nums) == 0:
return []
if len(nums) == 1:
return nums
count1, c1, count2, c2 = 1, nums[0], 0, 0
i = 1
while nums[i] == nums[0]:
count1 += 1
i += 1
if i >= len(nums):
break
if i == len(nums):
return [c1]
c2 = nums[i]
count2 = 1
for j in range(i + 1, len(nums)):
if count1 != 0 and count2 != 0:
if nums[j] == c1:
count1 += 1
elif nums[j] == c2:
count2 += 1
else:
count1 -= 1
count2 -= 1
elif count1 == 0 and count2 != 0:
if nums[j] == c2:
count2 += 1
else:
c1 = nums[j]
count1 += 1
elif count1 != 0 and count2 == 0:
if nums[j] == c1:
count1 += 1
else:
c2 = nums[j]
count2 += 1
else:
c1 = nums[j]
count1 += 1
result = []
count1, count2 = 0, 0
for i in range(len(nums)):
if nums[i] == c1:
count1 += 1
elif nums[i] == c2:
count2 += 1
if count1 > len(nums) / 3:
result.append(c1)
if count2 > len(nums) / 3:
result.append(c2)
return result