多米诺骨牌等价对的数量 | 豆包MarsCode AI刷题

41 阅读2分钟

解题思路

  1. 理解等价性

    • 对于两张多米诺骨牌 [a, b] 和 [c, d],它们等价当且仅当 (a == c 且 b == d) 或者 (a == d 且 b == c)
  2. 数据结构选择

    • 使用哈希表(HashMap)来记录每种多米诺骨牌的出现次数。由于多米诺骨牌可以旋转,我们需要将每张牌标准化(例如,总是将较小的数放在前面)。
  3. 算法步骤

    • 标准化多米诺骨牌:遍历每张多米诺骨牌,将其标准化(例如,总是将较小的数放在前面)。
    • 记录出现次数:使用哈希表记录每种标准化后的多米诺骨牌的出现次数。
    • 计算等价对:对于每种多米诺骨牌,计算其等价对的数量。如果有 n 张相同的牌,那么等价对的数量是 n * (n - 1) / 2

具体步骤

  1. 标准化多米诺骨牌

    • 对于每张多米诺骨牌 [a, b],将其标准化为 min(a, b), max(a, b)。这样可以确保相同的牌有相同的表示。
  2. 记录出现次数

    • 遍历每张多米诺骨牌,将其标准化后的表示作为键,记录在哈希表中。
  3. 计算等价对

    • 遍历哈希表中的值,计算每种多米诺骨牌的等价对数量,并累加得到最终结果。
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);
    }
}

关键步骤

  1. 标准化多米诺骨牌

    • 使用 normalize 方法将每张多米诺骨牌标准化,确保相同的牌有相同的表示。
  2. 使用哈希表记录出现次数

    • 遍历每张多米诺骨牌,将其标准化后的表示作为键,记录在哈希表中。
  3. 计算等价对

    • 遍历哈希表中的值,计算每种多米诺骨牌的等价对数量,并累加得到最终结果。