在一個數組中尋找多數元素
阿新 • • 發佈:2022-05-15
問題描述
多數元素是指出現次數大於陣列總長度一半的元素,如陣列[1,3,3,3,5,7,3],陣列長度為7,元素3出現了4次,大於7/2=3,所以元素3為多數元素。
遍歷計數法
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; class Solution { public int majorityElement(int[] nums) { Map<Integer, Integer> map = new HashMap<>(); for (int num : nums) { map.put(num, map.getOrDefault(num, 0) + 1); } for (Entry<Integer, Integer> entry : map.entrySet()) { if (entry.getValue() > (nums.length / 2)) { return entry.getKey(); } } return -1; } public static void main(String[] args) { System.out.println(new Solution().majorityElement(new int[]{2, 2, 1, 1, 1, 2, 2})); } }
使用一個HashMap儲存每一個元素和它出現的次數。
排序取中項法(前提存在多數元素)
import java.util.Arrays; class Solution { public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length / 2]; } public static void main(String[] args) { System.out.println(new Solution().majorityElement(new int[]{2, 2, 1, 1, 1, 2, 2})); } }
在一個排好序的陣列中,其中間的元素必定是多數元素(如果存在的話)。
使用位運算(前提存在多數元素)
class Solution { public int majorityElement(int[] nums) { int res = 0; int n = nums.length; for (int i = 0; i < 32; i++) { int ones = 0, zeros = 0; for (int num : nums) { if (ones > n / 2 || zeros > n / 2) { break; } //num在第i位的值,如3在第0位的值為1,num&(1<<i)的結果要麼為0,要麼為(1<<i) int bit = num & (1 << i); if (bit == 0) { zeros++; } else { ones++; } } if (ones > zeros) { //將res的第i位置為1,如將3的第2位置為1,就變成了7 res |= (1 << i); } } return res; } public static void main(String[] args) { System.out.println(new Solution().majorityElement(new int[]{2, 2, 1, 1, 1, 2, 2})); } }
以陣列[1,3,3,3,5,7,3]為例,元素3為多數元素,3的二進位制表示為
00000000 00000000 00000000 00000011
那麼在0位和1位這兩個位置的1一定比0多,因為元素3已經佔一半以上了。
摩爾投票法(前提存在多數元素)
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
int res = 0;
for (int num : nums) {
if (count == 0) {
count = 1;
res = num;
} else {
if (res == num) {
count++;
} else {
count--;
}
}
}
return res;
}
public static void main(String[] args) {
System.out.println(new Solution().majorityElement(new int[]{2, 2, 1, 1, 1, 2, 2}));
}
}
核心原理就是對拼消耗
,假設有A,B兩個國家,A人口占總人口的一半以上,那麼只要A國一個人能夠消耗掉B國一個人,最後剩下的一定是A國人,就算B國人內鬥也不影響最終結果。
帶入到程式碼中,以陣列[1,3,3,3,5,7,3]為例,元素1為B國人,元素3為A國人,最終對拼消耗之後還剩一個3。
以陣列[1,1,2,2,3,3,3,3,3]為例,1,2元素都屬於B國人,剛開始就是1和2相互消耗(內鬥),最後剩下的還是3。
參考
演算法設計:尋找多數元素
[LeetCode] 169. Majority Element 求大多數
如何理解摩爾投票演算法?