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.
Solution1:Moore voting
和169題思路Solution1相同: http://www.lxweimin.com/p/931ed67158fe
思路:主要思想是每次找到三個不同的元素 一起棄掉,最終剩下的就是有可能是是出現過>n/3的。
最多只能有兩個出現過>n/3次的,所以定義兩個candidates,如果有的話,Moore voting會選出來,但題目沒有guarantee,所以最后需要再遍歷count來double check。
Time Complexity: O(N) Space Complexity: O(1)
Solution2:二分治來找到最多出現的兩個 再check?
Solution3:Sort
思路:sort后 找到 1/3處 和 2/3處 這兩個candidates 。再double check 是否超過n/3次,check的方式因為已經排好序,可以binary search 找 起始位置和終止位置,check類似81題:http://www.lxweimin.com/p/597d80b0c161
Solution3 refer: https://discuss.leetcode.com/topic/65330/a-binary-search-solution-assuming-the-input-array-is-sorted-beats-99/2
Code: not finished
Solution4:Hashmap
Solution1 Code:
class Solution1 {
// Moore voting algorithm
public List<Integer> majorityElement(int[] nums) {
List<Integer> result = new ArrayList<Integer>();
int candidate1 = 0, candidate2 = 0; // there are max two candidates
int count1 = 0, count2 = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == candidate1) {
count1++;
} else if (nums[i] == candidate2) {
count2++;
} else if(count1 == 0) {
candidate1 = nums[i];
count1 = 1;
} else if(count2 == 0) {
candidate2 = nums[i];
count2 = 1;
} else {
count1--;
count2--;
}
}
// check two candidiates, since there is no guarantee there are two that appear > n / 3
count1 = 0;
count2 = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == candidate1)
count1++;
else if (nums[i] == candidate2)
count2++;
}
if (count1 > nums.length / 3)
result.add(candidate1);
if (count2 > nums.length / 3)
result.add(candidate2);
return result;
}
}