1. 程式人生 > >筆試面試演算法經典-找到陣列中出現次數大於N/k的數(Java)

筆試面試演算法經典-找到陣列中出現次數大於N/k的數(Java)

題目
給定一個整型陣列arr,再給定一個整數k,列印所有出現次數大於 N/K 的數。如果沒有這樣的數,列印提示資訊。
要求
時間複雜度為O(N*K),額外空間複雜度為O(K)。

思路

每次從陣列中刪除 K 個不同的數,如果某個數的次數大於 N/K ,這個數最後肯定會剩下來,數學證明:假設 X 的次數為 (N/k+1) > N/K ,如果每次刪除 k個不同的數最後數組裡面剩餘的數裡面沒有 X 那麼肯定刪除的次數大於等於(N/k+1)>N/K , 那麼:K*(N/K+1)>N,不成立因為陣列中只有 N 個數不可能刪除掉 比 N 還多的數。

注意:刪除後剩餘的數不一定全是次數大於 N/K 的數,例如:{1,2,3} k=2, 刪除後陣列中還剩餘 3,但是 3 的次數為 1 ,因此還要看剩餘的數的次數是不是大於 N/K.

演算法過程:大小為 K 的空間,來儲存不同的數,當有K個不同的數時,將每個數的次數減 1當 將次數為1的數刪除,如果空間中有這個數時,則將這個數的次數加 1 。

下面是陣列arr[]={1 ,2 ,3 ,3 ,5 ,2 ,2 ,3 ,3 ,3 ,5 ,6 ,2 ,2 ,2 ,3 , 3}處理的簡單過程圖:
這裡寫圖片描述

程式碼:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
public class GetKMajor {

    public static void
main(String[] args) { int arr[]={1,2,3,3,5,2,2,3,3,3,5,6,2,2,2,3,3}; int k=3; getKMajor(arr,k); } public static void getKMajor(int arr[],int k) { if(k<2) { return; } HashMap<Integer, Integer> hashMap=new HashMap<Integer, Integer>(); for
(int i=0;i<arr.length;i++) { //hashmap由於儲存k個不同的數,當hashmap中有k個不同的數時,則每個數的次數減1, //如果某個數的次數為0,則將其從hashmap中刪除。 if(hashMap.containsKey(arr[i])) { //如果hashmap中存在這個數,則將這個數的次數加1 hashMap.put(arr[i],hashMap.get(arr[i])+1); } else { if(hashMap.size()==k-1) { //如果hashmap中不存在這個數,如此時hashmap中存在k-1個不同的數則將 //hashmap中的每個數的次數減1 AllminusOne(hashMap); } else { //hashmap中的不同數個數小於k-1,時將該數加入到hashmap中。 hashMap.put(arr[i], 1); } } } for(Entry<Integer, Integer> set:hashMap.entrySet()) { Integer key=set.getKey(); hashMap.put(key, 0); //對hashmap中剩下的每個數先將次數賦值為0,為後面計算每個數的次數是否大於N/K做準備。 } for(int i=0;i<arr.length;i++) { if(hashMap.containsKey(arr[i])) { hashMap.put(arr[i], hashMap.get(arr[i])+1); } } for(Entry<Integer, Integer> set:hashMap.entrySet()) { Integer key=set.getKey(); Integer value=set.getValue(); if(value>arr.length/k) System.out.println(key); //如果某個數的次數大於K/N則將其輸出。 } } public static void AllminusOne(HashMap<Integer, Integer> hashMap) { //將hashmap中的每個數的次數減1,將減 1 後次數為0 的從hashmap中刪除。 ArrayList<Integer> removelist=new ArrayList<Integer>(); for(Entry<Integer, Integer> set:hashMap.entrySet()) { Integer key=set.getKey(); Integer value=set.getValue(); if(value==1) { removelist.add(key); }else { hashMap.put(key, value-1); } } for(Integer removekey:removelist) { hashMap.remove(removekey); } } }