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中,实在是秒啊。通过一次循环遍历即遍历完整题的要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值