LeetCode每日一题2025-05-04
1128. 等价多米诺骨牌对的数量 E
给你一组多米诺骨牌 dominoes 。
形式上,dominoes[i] = [a, b] 与 dominoes[j] = [c, d] 等价 当且仅当 (a == c 且 b == d) 或者 (a == d 且 b == c) 。即一张骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌。
在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。
示例 1:
1 | 输入:dominoes = [[1,2],[2,1],[3,4],[5,6]] |
示例 2:
1 | 输入:dominoes = [[1,2],[1,2],[1,1],[1,2],[2,2]] |
提示:
1 <= dominoes.length <= 4 * 10⁴dominoes[i].length == 21 <= dominoes[i][j] <= 9
问题分析
- 给你一个多米诺骨牌列表
dominoes,每个骨牌是一个长度为 2 的数组[a, b]。 - 如果两张骨牌旋转后能完全一致,就称它们等价。
- 例如
[1,2]与[2,1]等价。我们要统计所有满足等价关系的骨牌对(i, j)的总数。
算法思路
-
规范化(标准化)表示
- 每张骨牌
[a, b],将它变成有序对(min(a,b), max(a,b))。 - 这样无论原来是
[1,2]还是[2,1],都统一映射为为(1,2)。
- 每张骨牌
-
哈希表计数
- 用一个字典(或 Python 的
Counter)记录每种“规范化后”的骨牌出现了多少次。 - 键(key)就是那个二元组,值(value)就是出现次数。
- 用一个字典(或 Python 的
-
组合数学计算对数
-
如果某种骨牌规范后出现了 次,那么这 张骨牌两两之间都能组成等价对,共有组合数
-
把所有不同骨牌规范的组合数累加,就是答案。
-
时间复杂度
- 时间复杂度:遍历一次骨牌列表 ,再遍历一次哈希表(最坏也是 ),总体 。
- 空间复杂度:哈希表存储规范后骨牌的计数,最坏情况键值对有 个。
代码分解
-
初始化计数字典
1
2from collections import Counter
count = Counter() -
标准化并计数
1
2
3for a, b in dominoes:
key = (a, b) if a <= b else (b, a) # 保证顺序
count[key] += 1 -
组合数学求配对数
1
2
3for k in count.values():
if k > 1:
result += k*(k-1)//2的计算公式直接用整数运算实现
代码实现
1 | class Solution: |
以 [[1,2], [2,1], [3,4], [5,6]] 为例:
| 原始骨牌 | 规范化后 | 累计到哈希表中 |
|---|---|---|
| [1,2] | (1,2) | count[(1,2)] = 1 |
| [2,1] | (1,2) | count[(1,2)] = 2 |
| [3,4] | (3,4) | count[(3,4)] = 1 |
| [5,6] | (5,6) | count[(5,6)] = 1 |
最终哈希表 count 为:
1 | { |
接下来计算组合数:
- 对
(1,2),出现次数 ,组合数 (3,4)与(5,6)都只出现过 1 次,不会贡献配对(因为 )
所以总对数 = 1。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Stay hungry. Stay foolish.!
评论
