LeetCode 1128 等价多米诺骨牌对的数量 题解
今天的每日一题,我的思路还是硬做,不如评论区通过状压写的简单,但是答题思路加算法实现是没有问题的,且时间复杂度也是可以通过的,毕竟全是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中,实在是秒啊。通过一次循环遍历即遍历完整题的要求。