【LeetCode】1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量(Easy)(JAVA)每日一题

【LeetCode】1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量(Easy)(JAVA)

题目地址: https://leetcode.com/problems/number-of-equivalent-domino-pairs/

题目描述:

Given a list of dominoes, dominoes[i] = [a, b] is equivalent to dominoes[j] = [c, d] if and only if either (a == c and b == d), or (a == d and b == c) - that is, one domino can be rotated to be equal to another domino.

Return the number of pairs (i, j) for which 0 <= i < j < dominoes.length, and dominoes[i] is equivalent to dominoes[j].

Example 1:

Input: dominoes = [[1,2],[2,1],[3,4],[5,6]]
Output: 1

Constraints:

  • 1 <= dominoes.length <= 40000
  • 1 <= dominoes[i][j] <= 9

题目大意

给你一个由一些多米诺骨牌组成的列表 dominoes。

如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。

形式上,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 a == c 且 b == d,或是 a == d 且 b == c。

在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。

解题方法

暴力循环

  1. 直接用暴力双重循环,时间复杂度 O(n^2)
  2. 直接超时
class Solution {
    public int numEquivDominoPairs(int[][] dominoes) {
        int res = 0;
        for (int i = 0; i < dominoes.length; i++) {
            for (int j = i + 1; j < dominoes.length; j++) {
                if (dominoes[i][0] == dominoes[j][0] && dominoes[i][1] == dominoes[j][1]) {
                    res++;
                } else if (dominoes[i][0] == dominoes[j][1] && dominoes[i][1] == dominoes[j][0]) {
                    res++;
                }
            }
        }
        return res;
    }
}

超出时间限制

优化一

  1. 对数组先进行排序,时间复杂度 O(nlogn)
  2. 再找出重复的
class Solution {
    public int numEquivDominoPairs(int[][] dominoes) {
        for (int i = 0; i < dominoes.length; i++) {
            if (dominoes[i][0] <= dominoes[i][1]) continue;
            int temp = dominoes[i][0];
            dominoes[i][0] = dominoes[i][1];
            dominoes[i][1] = temp;
        }
        Arrays.sort(dominoes, (a, b) -> (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));
        int res = 0;
        for (int i = 0; i < dominoes.length; i++) {
            int next = i + 1;
            while (next < dominoes.length && dominoes[i][0] == dominoes[next][0] && dominoes[i][1] == dominoes[next][1]) {
                next++;
            }
            int len = next - i;
            res += len * (len - 1) / 2;
            i = next - 1;
        }
        return res;
    }
}

执行耗时:15 ms,击败了23.27% 的Java用户
内存消耗:47.7 MB,击败了35.18% 的Java用户

优化二

  1. 因为 1 <= dominoes[i][j] <= 9, 可以用一个 y = 10 * x + z 来表示 dominoes[i] 整体的值
  2. 用一个数组来存储即可,时间复杂度 O(n)
  3. note: 因为这里总共才 100 个数,用数组来存可以更快,Map 消耗空间大而且存取速度慢; x 和 z 可以交换位置,所以 x 代表较小的数,z 代表较大的数
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;
    }
}

执行耗时:3 ms,击败了85.51% 的Java用户
内存消耗:47.6 MB,击败了51.03% 的Java用户

欢迎关注我的公众号,LeetCode 每日一题更新

猜你喜欢

转载自blog.csdn.net/qq_16927853/article/details/113172972