[算法]在数组中找到出现次数大于N/K的数
题目:
1.给定一个整型数组,打印其中出现次数大于一半的数。如果没有出现这样的数,打印提示信息。
如:1,2,1输出1。 1,2,3输出no such number。
2.给定一个整型数组,再给一个整数K,打印所有出现次数大于N/K的数,如果没有这样的数,打印提示信息。
解答:
两道题都可以使用哈希表记录每个数出现的次数,额外的空间复杂度为O(N)。
其他的方法:
1.时间复杂度为O(N)。额外空间复杂度为O(1)。
public static void printHalfMajor(int[] arr) { int cand = 0; int times = 0; for (int i = 0; i < arr.length; i++) { if (times == 0) { cand = arr[i]; times++; } else if (arr[i] == cand) { times++; } else { times--; } } times = 0; for (int i = 0; i < arr.length; i++) { if (arr[i] == cand) times++; } if (times > arr.length / 2) { System.out.println(cand); } else { System.out.println("no such number."); } }
第一个for循环结束后,如果这样的数真的存在,那么cand的值就是所求的值。但是cand的值不一定就是所求的值。所以最后还要用for循环判断一下。
2.时间复杂度为O(N*K)。额外空间复杂度为O(K)。
public static void printKMajor(int[] arr, int K) { if (K < 2) { System.out.println("the value of K is invalid."); return; } HashMap<Integer, Integer> cands = new HashMap<Integer, Integer>(); 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<Integer, Integer> reals = getReals(arr, cands); boolean hasPrint = false; for (Entry<Integer, Integer> set : cands.entrySet()) { Integer key = set.getKey(); if (reals.get(key) > arr.length / K) { hasPrint = true; System.out.print(key + " "); } } System.out.println(hasPrint ? "" : "no such number."); } public static void allCandsMinusOne(HashMap<Integer, Integer> map) { List<Integer> removeList = new LinkedList<Integer>(); for (Entry<Integer, Integer> 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); } } public static HashMap<Integer, Integer> getReals(int[] arr, HashMap<Integer, Integer> cands) { HashMap<Integer, Integer> reals = new HashMap<Integer, Integer>(); 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; }