問題描述
給定n個正整數,找出它們中出現次數最多的數。如果這樣的數有多個,請輸出其中最小的一個。
輸入格式
輸入的第一行只有一個正整數n(1 ≤ n ≤ 1000),表示數字的個數。
輸入的第二行有n個整數s1, s2, …, sn (1 ≤ si ≤ 10000, 1 ≤ i ≤ n)。相鄰的數用空格分隔。
輸出格式
輸出這n個次數中出現次數最多的數。如果這樣的數有多個,輸出其中最小的一個。
樣例輸入
6
10 1 10 20 30 20
樣例輸出
10
CCF官網給出的源碼:
import java.util.*; public class Main { public static void main(String[] args) { new Main().run(); } public void run() { Scanner fin = new Scanner(System.in); int N = fin.nextInt(); //輸入數字個數 int[] count = new int[10001];//這裏設數組大小爲10001是防止輸入的數超過數組的下標值 for (int i = 0; i < N; ++i) { //對於數組count,下標i代表每個數,count[i]代表i出現的次數 //數組只開闢了空間不賦值的默認值爲0,若數字10只出現2次,則count[10]=2 ++count[fin.nextInt()]; } int maxCount = -1; int result = 0; for (int i = 1; i <= 10000; ++i) { //i從1開始增大,滿足“出現次數最多的數有多個,輸出其中最小的一個”條件 if (count[i] > maxCount) { maxCount = count[i]; result = i; } } System.out.println(result); } }
這種解法簡單但耗費時間和資源,同時也不好想,涉及到數值和次數兩個記錄值,相信多數人會想到用可以保存鍵值對的HashMap解決,下面給出這種常規解法:
import java.util.*; public class Main{ public static void main(String args[]){ Scanner scanner = new Scanner(System.in); int N = Scanner.nextInt(); int arr[] = new int[N]; for(int i=0;i<N;i++){ arr[i] = scanner.nextInt(); } Map<Integer,Integer> map = new HashMap<Integer,Integer>(); for(int i=0;i<arr.length;i++){ if(map.containsKey(arr[i])){ map.put(arr[i],map.get(arr[i])+1); }else{ map.put(arr[i],1); } } List<Map.Entry<Integer,Integer>> list = new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet()); Collections.sort(list,new Comparator<Map.Entry<Integer,Integer>>(){ //需要重寫compare()方法(默認升序),改成按value降序 public int compare(Map.Entry<Integer,Integer> o1,Map.Entry<Integer,Integer> o2){ return(o2.getValue()-o1.getValue());//返回值爲正,則將2個對象對調 } }); System.out.println(list.get(0).getKey()); //獲取出現次數最多的那個數 } }
Collections.sort()方法中的參數Comparator是比較器,它本身只負責比較兩個數據,然後把結果返回,至於它的調用者獲的返回結果後如何處理它不管,也就是說Comparator本身不負責排序,只負責比較,排序處理是它的調用者實現的,也就是在sort方法裏實現的。