package class007; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; public class Code04_FindKMajor { public static List kMajor(int[] arr, int K) { List ans = new ArrayList<>(); if (K < 2) { return ans; } // 候选表,记录数一定是O(K) > N/K k-1 HashMap cands = new HashMap(); for (int i = 0; i != arr.length; i++) { if (cands.containsKey(arr[i])) { cands.put(arr[i], cands.get(arr[i]) + 1); } else { if (cands.size() == K - 1) { allCandsMinusOne(cands); } else { cands.put(arr[i], 1); } } } HashMap reals = getReals(arr, cands); for (Entry set : cands.entrySet()) { Integer key = set.getKey(); if (reals.get(key) > arr.length / K) { ans.add(key); } } return ans; } public static void allCandsMinusOne(HashMap map) { List removeList = new LinkedList(); for (Entry set : map.entrySet()) { Integer key = set.getKey(); Integer value = set.getValue(); if (value == 1) { removeList.add(key); } map.put(key, value - 1); } for (Integer removeKey : removeList) { map.remove(removeKey); } } // for test public static List right(int[] arr, int K) { List ans = new ArrayList<>(); if (K < 2) { return ans; } HashMap times = new HashMap<>(); for (int num : arr) { if (!times.containsKey(num)) { times.put(num, 1); } else { times.put(num, times.get(num) + 1); } } for (Entry entry : times.entrySet()) { if (entry.getValue() > arr.length / K) { ans.add(entry.getKey()); } } return ans; } public static HashMap getReals(int[] arr, HashMap cands) { HashMap reals = new HashMap(); for (int i = 0; i != arr.length; i++) { int curNum = arr[i]; if (cands.containsKey(curNum)) { if (reals.containsKey(curNum)) { reals.put(curNum, reals.get(curNum) + 1); } else { reals.put(curNum, 1); } } } return reals; } public static int[] genareteRandomArray(int len, int max) { int[] ans = new int[(int) (Math.random() * len) + 1]; for (int i = 0; i < ans.length; i++) { ans[i] = (int) (Math.random() * max) + 1; } return ans; } public static boolean isEqual(List ans1, List ans2) { if (ans1.size() != ans2.size()) { return false; } HashSet set1 = new HashSet<>(); for (Integer num : ans1) { set1.add(num); } if (set1.size() != ans1.size()) { return false; } for (Integer num : ans2) { set1.remove(num); } return set1.size() == 0; } public static void main(String[] args) { int len = 100; int max = 10; int K = 5; int testTime = 100000; System.out.println("test begin"); for (int i = 0; i < testTime; i++) { int[] arr = genareteRandomArray(len, max); List ans1 = kMajor(arr, K); List ans2 = right(arr, K); if (!isEqual(ans1, ans2)) { System.out.println("Oops!"); break; } } System.out.println("test end"); } }