【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) 的数量。
解题方法
暴力循环
- 直接用暴力双重循环,时间复杂度 O(n^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;
}
}
超出时间限制
优化一
- 对数组先进行排序,时间复杂度 O(nlogn)
- 再找出重复的
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 <= dominoes[i][j] <= 9, 可以用一个 y = 10 * x + z 来表示 dominoes[i] 整体的值
- 用一个数组来存储即可,时间复杂度 O(n)
- 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用户