题目:
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; } };
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; } }
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