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

107 阅读3分钟

一. 问题描述

小F手里有一组多米诺骨牌,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价当且仅当 (a == c 且 b == d) 或者 (a == d 且 b == c)。也就是说,一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张等价的多米诺骨牌。

现在,小F想知道在 0 <= i < j < dominoes.length 的前提下,有多少对多米诺骨牌是等价的。

测试样例

样例1:

输入:dominoes = [[1, 2], [2, 1], [3, 4], [5, 6]]
输出:1

样例2:

输入:dominoes = [[1, 2], [2, 1], [1, 2], [2, 1]]
输出:6

样例3:

输入:dominoes = [[3, 3], [3, 3], [3, 3], [3, 3]]
输出:6

二. 思路解析

2.1 问题理解

我们需要计算在给定的多米诺骨牌数组中,有多少对多米诺骨牌是等价的。等价的定义是:两张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张。也就是说,[a, b] 和 [b, a] 是等价的。

2.2 数据结构选择

为了高效地统计每个多米诺骨牌的出现次数,我们可以使用哈希表(HashMap)。哈希表的键可以是一个字符串,表示排序后的多米诺骨牌,值则是该多米诺骨牌出现的次数。

三. 解题步骤

3.1 算法步骤

  1. 遍历多米诺骨牌数组

    • 对于每个多米诺骨牌,先将其两个数字排序,确保 [a, b] 和 [b, a] 被视为相同的键。
    • 将排序后的多米诺骨牌转换为字符串,作为哈希表的键。
    • 更新哈希表中该键的计数。
  2. 计算等价对数

    • 对于哈希表中的每个键,如果一个多米诺骨牌出现了 count 次,那么等价对数为 count * (count - 1) / 2。这是因为从 count 个相同的骨牌中选择两个的组合数为 C(count, 2),即 count * (count - 1) / 2
  3. 返回结果

    • 将所有等价对数相加,得到最终的结果。

3.2 复杂度分析

  • 时间复杂度:O(n log n),其中 n 是多米诺骨牌的数量。排序每个多米诺骨牌需要 O(log n) 的时间,遍历所有多米诺骨牌需要 O(n) 的时间。
  • 空间复杂度:O(n),用于存储哈希表。

四. Code

import java.util.Arrays;
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) {
            // 将多米诺骨牌的两个数字排序,确保 [a, b] 和 [b, a] 被视为相同的键
            Arrays.sort(domino);
            // 将多米诺骨牌转换为字符串作为键
            String key = Arrays.toString(domino);
            // 更新哈希表中的计数
            countMap.put(key, countMap.getOrDefault(key, 0) + 1);
        }
        
        int pairs = 0;
        // 计算等价对数
        for (int count : countMap.values()) {
            // 如果一个多米诺骨牌出现了 count 次,那么等价对数为 count * (count - 1) / 2
            pairs += count * (count - 1) / 2;
        }
        
        return pairs;
    }

    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);
    }
}

五. 总结

使用AI进行题解是一种高效且准确的学习辅助工具,能够帮助用户快速理解复杂的算法问题。然而,用户仍需保持独立思考和学习的能力,避免过度依赖AI。通过结合AI的辅助和自身的努力,用户可以更好地提升编程技能和解决问题的能力。