解题思路
-
理解等价性:
- 对于两张多米诺骨牌
[a, b]和[c, d],它们等价当且仅当(a == c 且 b == d)或者(a == d 且 b == c)。
- 对于两张多米诺骨牌
-
数据结构选择:
- 使用哈希表(
HashMap)来记录每种多米诺骨牌的出现次数。由于多米诺骨牌可以旋转,我们需要将每张牌标准化(例如,总是将较小的数放在前面)。
- 使用哈希表(
-
算法步骤:
- 标准化多米诺骨牌:遍历每张多米诺骨牌,将其标准化(例如,总是将较小的数放在前面)。
- 记录出现次数:使用哈希表记录每种标准化后的多米诺骨牌的出现次数。
- 计算等价对:对于每种多米诺骨牌,计算其等价对的数量。如果有
n张相同的牌,那么等价对的数量是n * (n - 1) / 2。
具体步骤
-
标准化多米诺骨牌:
- 对于每张多米诺骨牌
[a, b],将其标准化为min(a, b), max(a, b)。这样可以确保相同的牌有相同的表示。
- 对于每张多米诺骨牌
-
记录出现次数:
- 遍历每张多米诺骨牌,将其标准化后的表示作为键,记录在哈希表中。
-
计算等价对:
- 遍历哈希表中的值,计算每种多米诺骨牌的等价对数量,并累加得到最终结果。
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int solution(int[][] dominoes) {
// 创建一个哈希表来记录每种多米诺骨牌的出现次数
Map<String, Integer> countMap = new HashMap<>();
// 遍历每张多米诺骨牌
for (int[] domino : dominoes) {
// 标准化多米诺骨牌
String key = normalize(domino);
// 更新哈希表中的计数
countMap.put(key, countMap.getOrDefault(key, 0) + 1);
}
// 计算等价对的数量
int pairs = 0;
for (int count : countMap.values()) {
// 如果有 n 张相同的牌,等价对的数量是 n * (n - 1) / 2
pairs += count * (count - 1) / 2;
}
return pairs;
}
// 标准化多米诺骨牌,总是将较小的数放在前面
private static String normalize(int[] domino) {
int a = domino[0];
int b = domino[1];
return (a < b) ? a + "," + b : b + "," + a;
}
public static void main(String[] args) {
System.out.println(solution(new int[][]{{1, 2}, {2, 1}, {3, 4}, {5, 6}}) == 1);
System.out.println(solution(new int[][]{{1, 2}, {2, 1}, {1, 2}, {2, 1}}) == 6);
System.out.println(solution(new int[][]{{3, 3}, {3, 3}, {3, 3}, {3, 3}}) == 6);
}
}
关键步骤
-
标准化多米诺骨牌:
- 使用
normalize方法将每张多米诺骨牌标准化,确保相同的牌有相同的表示。
- 使用
-
使用哈希表记录出现次数:
- 遍历每张多米诺骨牌,将其标准化后的表示作为键,记录在哈希表中。
-
计算等价对:
- 遍历哈希表中的值,计算每种多米诺骨牌的等价对数量,并累加得到最终结果。