等价多米诺骨牌对的数量
难度:
标签:
题目描述
代码结果
运行时间: 28 ms, 内存: 22.9 MB
/*
* Problem: Given a list of dominoes, find the number of pairs (i, j) such that dominoes[i] and dominoes[j] are equivalent.
* Two dominoes [a, b] and [c, d] are equivalent if and only if (a == c and b == d) or (a == d and b == c).
*
* Approach:
* 1. Use Java Streams to count the frequency of each domino configuration. Normalize each domino to a consistent form (min, max).
* 2. For each domino configuration, if the count is more than 1, calculate the number of valid pairs using the combination formula n * (n - 1) / 2.
*/
import java.util.*;
import java.util.stream.Collectors;
public class DominoPairsStream {
public int numEquivDominoPairs(int[][] dominoes) {
Map<String, Long> map = Arrays.stream(dominoes)
.map(domino -> {
int a = domino[0];
int b = domino[1];
return a < b ? a + "," + b : b + "," + a;
})
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
return map.values().stream()
.filter(val -> val > 1)
.mapToInt(val -> (int) (val * (val - 1) / 2))
.sum();
}
}
解释
方法:
本题目的主要思路是使用哈希表来统计每种多米诺骨牌出现的次数。首先,对于每一对多米诺骨牌 [x, y],为了避免旋转后的等价性问题,我们首先将每对多米诺骨牌按照元素大小排序,确保较小的数字总是在前。这样,每一对可以唯一地表示为两位数 val = min(x, y) * 10 + max(x, y)。利用一个长度为 100 的数组 num 来统计每种 val 的出现次数。对于每一对多米诺骨牌,如果它在之前已经出现过,那么它能与之前的每一对形成一个新的等价对。因此,每次遇到同样的 val,当前的等价对数就是 val 已经出现的次数,我们把这个数累加到结果 ret 中。随后,更新这个 val 的出现次数。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在哈希表解法中,为什么选择将多米诺骨牌的数对转换成一个两位数来表示,而不是使用元组或其他数据结构直接存储?
▷🦆
在计算两位数 val 时使用的公式 `val = min(x, y) * 10 + max(x, y)` 是否有可能造成不同的多米诺骨牌对应同一个 val 值?
▷🦆
给定最大多米诺骨牌数为 40,000,数组长度为 100 用来记录所有可能的多米诺骨牌组合是否足够?存在溢出或冲突的可能吗?
▷🦆
题解中提到每遇到一个已存在的 val 就将其出现次数加到结果中,这种方法是否考虑了多米诺骨牌之间的不同组合次数?例如同样的多米诺骨牌重复出现的情况。
▷