1. 程式人生 > 實用技巧 >給你一個整數陣列 arr,請你幫忙統計陣列中每個數的出現次數

給你一個整數陣列 arr,請你幫忙統計陣列中每個數的出現次數

題目: 

/* 給你一個整數陣列arr,請你幫忙統計陣列中每個數的出現次數。
 *
 * 如果每個數的出現次數都是獨一無二的,就返回true;否則返回 false。
 *
 * 
 *
 * 示例 1:
 *
 * 輸入:arr = [1,2,2,1,1,3]
 * 輸出:true
 * 解釋:在該陣列中,1 出現了 3 次,2 出現了 2 次,3 只出現了 1 次。沒有兩個數的出現次數相同。
 * 示例 2:
 *
 * 輸入:arr = [1,2]
 * 輸出:false
 * 示例 3:
 *
 * 輸入:arr = [-3,0,1,-3,1,1,1,-3,10,0]
 * 輸出:true
 *
 * 來源:力扣(LeetCode)
 * 連結:https://leetcode-cn.com/problems/unique-number-of-occurrences
 * 著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
 */

  這是自己寫的方法:

  邏輯為:第一步遍歷arr,用map裝載<元素,出現次數>

      第二步建立另一個map2(用來裝載map的<出現次數,object>),並遍歷map的keySet,

      int o=(int)iterator.next();獲取對應元素的出現次數,並判斷是否在map2中出現,如果已經存在,則返回false,並break

  遍歷全arr + 取出元素+判斷是否存在map中 + 不在就新增進map|在就break

public class test01 {
    public static boolean uniqueOccurrences(int[] arr) {
        boolean flag=true;
        //1.使用map來裝載陣列內的引數和引數出現的次數
        HashMap<Integer,Integer> map=new HashMap();
        HashMap keyMap=new HashMap();
        map=getTimes(arr);
        //2.迴圈遍歷map,如果有重複的 則break,返回false
        //獲取map的鍵值集合並遍歷
        Set set=map.keySet();
        Iterator iterator=set.iterator();
        while(iterator.hasNext()){
            int o=(int)iterator.next();
            Object k=map.get(o);
            //如果集合包含k,說明重複,break,返回false
            if(keyMap.containsKey(k)){
                flag=false;
                break;
            }
            keyMap.put(k,0);
        }
        return flag;
    }

    /**
     1.輸入引數:陣列
     2.輸出引數:HashMap
     3.實現功能:統計陣列內各個元素出現的次數*/
    public static HashMap<Integer,Integer> getTimes(int[] arr){
        HashMap<Integer,Integer> h1=new HashMap();
        h1.put(arr[0],1);
        for(int i=1;i<arr.length;i++){
            if(h1.containsKey(arr[i])){
                int times=h1.get(arr[i]);
                h1.put(arr[i],++times);
            }else{
                h1.put(arr[i],1);
            }
        }
        return h1;
    }

//    public static void main(String[] args) { //--曾志偉的 執行16秒
//
//        int[] arr=new int[10000];
//    for(int i=0;i<10000;i++){
//        arr[i]=(int)(Math.random()*100)+1;
//    }
//        long startTime=System.currentTimeMillis();
//        boolean b=uniqueOccurrences(arr);
//        System.out.println(b);
//        long endTime=System.currentTimeMillis();                //獲得當前時間
//        System.out.println(endTime-startTime);
//    }
}

  

/**
 * 系統給出的答案:
 *
 * class Solution {
 *     public boolean uniqueOccurrences(int[] arr) {
 *         Map<Integer, Integer> occur = new HashMap<Integer, Integer>();
 *         for (int x : arr) {
 *             occur.put(x, occur.getOrDefault(x, 0) + 1);
 *         }
 *         Set<Integer> times = new HashSet<Integer>();
 *         for (Map.Entry<Integer, Integer> x : occur.entrySet()) {
 *             times.add(x.getValue());
 *         }
 *         return times.size() == occur.size();
 *     }
 * }
 *
 * 作者:LeetCode-Solution
 * 連結:https://leetcode-cn.com/problems/unique-number-of-occurrences/solution/du-yi-wu-er-de-chu-xian-ci-shu-by-leetcode-solutio/
 * 來源:力扣(LeetCode)
 * 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。*/

  

occur.getOrDefault(x, 0) + 1  通過這個map自帶的方法,直接代替了我原來的一整個方法(getTimes)。
他邏輯精妙之處,就在於 他取出了我將元素塞進map2的這個過程。他是將map的keyset對應的value(出現次數)放進Set集合,然後比較Set集合和原來map的長度。

總結:避免不必要的操作,例如開闢空間,多餘的塞資料操作等。