今天的每日一題,我的思路還是硬做,不如評論區通過狀壓寫的簡單,但是答題思路加算法實現是沒有問題的,且時間復雜度也是可以通過的,畢竟全是o(n)
那么我就來說一下我的思路,根據dominoes[i] = [a, b]
?與?dominoes[j] = [c, d]
?等價?當且僅當 (a == c
?且?b == d
) 或者 (a == d
?且?b == c
)可以知道我們需要將上述兩種情況總和到一起,那我們就可以常規使用map進行維護,但不同于以往的兩個Integer維護,我們這次需要改成String+Integer的map進行維護,而String則是代表i和j(dominoes[i][0]
和dominoes[i][1]
),而后面的Integer則代表數量,然后通過示例分析我們可以明白,如果前后存在3個、2個、1個可以這么統計的值的話我們可以使用公式sum*(sum-1)/2
得到。那么最后相加,結果就出來了。如果有解釋不到位的地方,結合代碼應該能理解的更快。
class Solution {public int numEquivDominoPairs(int[][] dominoes) {int n = dominoes.length;HashMap<String,Integer> hashmap = new HashMap<>();for(int i=0;i<n;i++){String key = "("+ dominoes[i][0] + "," + dominoes[i][1] + ")";String keyR = "(" + dominoes[i][1] + "," + dominoes[i][0] + ")";if(hashmap.getOrDefault(key,0)>0){hashmap.put(key,hashmap.getOrDefault(key,0)+1);}else if(hashmap.getOrDefault(keyR,0)>0){hashmap.put(keyR,hashmap.getOrDefault(keyR,0)+1);}else{hashmap.put(key,hashmap.getOrDefault(key,0)+1);}}int sum = 0;for(Map.Entry<String,Integer> entry:hashmap.entrySet()){// System.out.println("key="+entry.getKey()+" value="+entry.getValue());int mid = entry.getValue()*(entry.getValue()-1)/2;sum+=mid;}return sum;}
}
之后我們再來看看別人代碼的實現,不僅要總結自己的思路,我們也要吸取別人的思路做題,說不定哪天就用上了。
class Solution {public int numEquivDominoPairs(int[][] dominoes) {int[] num = new int[100];int ret = 0;for (int[] domino : dominoes) {int val = domino[0] < domino[1] ? domino[0] * 10 + domino[1] : domino[1] * 10 + domino[0];ret += num[val];num[val]++;}return ret;}
}
我們拿個示例來說一下
輸入:dominoes = [[1,2],[1,2],[1,1],[1,2],[2,2]]
輸出:3
比如這個示例
我們官方題解開的數組是100,是為了將雙下標變為單下標然后統計數量,比如1,2和2,1都變為12,然后再根據通過加加統計,當到第三個[1,2]
時,num[12]
已經統計至0+1+2=3了并計入ret中,實在是秒啊。通過一次循環遍歷即遍歷完整題的要求。