1128. 等价多米诺骨牌对的数量

题目描述

思路

  • 法一(哈希):把每个domino都转换成一个对象,该对象重写了hashCode和equals方法,当两个domino的两个数一样时认为这两个domino相等(tips:hashCode的结果也应该满足该条件)。遍历一遍计下每个domino出现的次数为count,然后将每个count*(count-1)/2相加即为最终结果。
  • 法二(二维转一维):观察到dominoes[i][j]为1到9之间的数。可以直接将domino转化为一个100以内的整数,这个整数的十位为domino中较大数,个位为domino中较小数。遍历一遍该数组,进行转化的同时使用一个int[100]数组记录每个数出现的次数count。最终将每个count*(count-1)/2相加即为最终结果。

哈希

java代码如下

import java.util.HashMap;
import java.util.Map;

class Solution {
    class Domino {
        int a;
        int b;

        public Domino(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int hashCode() {
            int hash = 17;
            hash = (hash + a * 31 + b * 31) * 31;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Domino) {
                Domino s = (Domino) obj;
                if ((s.a == this.a && s.b == this.b) || (s.a == this.b && s.b == this.a)) {
                    return true;
                } else {
                    return false;
                }
            }
            return super.equals(obj);
        }

    }

    public int numEquivDominoPairs(int[][] dominoes) {
        int length = dominoes.length;
        int res = 0;
        Map repeatMap = new HashMap<>();
        Map countMap = new HashMap<>();

        for (int i = 0; i < length; i++) {
            Domino domino = new Domino(dominoes[i][0], dominoes[i][1]);
            if (repeatMap.containsKey(domino)) {
                int value = repeatMap.get(domino) + 1;
                repeatMap.put(domino, value);
            } else {
                repeatMap.put(domino, 1);
            }
        }

        for (Integer value : repeatMap.values()) {
            if (value > 1) {
                if (countMap.containsKey(value)) {
                    res += countMap.get(value);
                } else {
                    countMap.put(value, value * (value - 1) / 2);
                    res += countMap.get(value);
                }
            }
        }

        return res;
    }
}

执行用时:13 ms, 在所有 Java 提交中击败了26.33%的用户
内存消耗:47.2 MB, 在所有 Java 提交中击败了96.09%的用户

结果不好,如果题目没有说明1 <= dominoes[i][j] <= 9的话结果应该是挺不错的。但是在这一条件下,有更好的方法。

二维转一维

java代码如下

class Solution {
    public int numEquivDominoPairs(int[][] dominoes) {
        int[] counts = new int[100];
        int length = dominoes.length;
        int res = 0;
        for (int i = 0; i < length; i++) {
            int num = transform(dominoes[i]);
            counts[num]++;
        }
        for (int i = 0; i < 100; i++) {
            int count = counts[i];
            if (count > 1) {
                res += count * (count - 1) / 2;
            }
        }
        return res;
    }

    public int transform(int[] nums) {
        int a = nums[0];
        int b = nums[1];
        int res = a > b ? a * 10 + b : b * 10 + a;
        return res;
    }
}

执行用时:2 ms, 在所有 Java 提交中击败了97.76%的用户
内存消耗:48 MB, 在所有 Java 提交中击败了9.46%的用户

ojbk

你可能感兴趣的:(1128. 等价多米诺骨牌对的数量)