1. 程式人生 > >8.7在陣列中找出出現次數大於N÷K的數

8.7在陣列中找出出現次數大於N÷K的數

題目

給定一個整形陣列arr,再給定一個整數K,列印所有出現次數大於N/K的數,如果沒有這樣的數,列印提示資訊。


首先分析K=2這個特殊情況,有以下思路:

  1. 排序後,取陣列中間的數。但該方法的時間複雜度為排序演算法的時間複雜度O(NlogN)。

  2. 一次在陣列中刪掉兩個不同的數,不停地刪除,直到剩下的數只有一種,一定是那個出現次數大於一半的數。

    實現程式碼:

    /**
     * 特例:找出出現次數大於一半的數
     *
     * @param arr 待查陣列
     */
    public 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 = 1; } 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."); } }

拓展思路二,回到K為不定項的情況,類似地,只需要立K-1個候選,然後有K-1個times統計即可。

程式碼實現如下:

public
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<>(); 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 (Map.Entry<Integer, Integer> set : cands.entrySet()) { Integer key = set.getKey(); if (reals.get(key) > arr.length / K) { hasPrint = true; System.out.println(key + " "); } } System.out.println(hasPrint ? "" : "No such number."); } /** * 每一個候選的點數都減一,並剔除減後點數為0的候選 * * @param map 所有候選 */ public void allCandsMinusOne(HashMap<Integer, Integer> map) { List<Integer> removeList = new LinkedList<>(); for (Map.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); } } /** * 得到所有候選的出現次數 * * @param arr 原陣列 * @param cands 所有候選 * @return map<候選數 , 出現次數> */ public HashMap<Integer, Integer> getReals(int[] arr, HashMap<Integer, Integer> cands) { HashMap<Integer, Integer> 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; }