Topic
给你一个由一些多米诺骨牌组成的列表 dominoes。
如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。
形式上,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 ac 且 bd,或是 ad 且 bc。
在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。
Example
输入:dominoes = [[1,2],[2,1],[3,4],[5,6]]
输出:1
tips
1 <= dominoes.length <= 40000
1 <= dominoes[i][j] <= 9
Solution_1
最简单的思路
先对dominoes中每一个数组进行排序
这样能够保证无论是交换后的数组相等还是交换前即可相等的数组都无需交换均相等
之后将dominoes从小到大进行排列
每两个数组间只要满足条件就要计算一次交换
所以对所有能交换的数组进行累加
利用数学公式n * (n - 1) // 2计算后
返回res 即可完成
Code 1
class Solution:
def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
res = 0
for i in range(0, len(dominoes)):
dominoes[i].sort()
dominoes.sort()
count = 1
for j in range(1, len(dominoes)):
if dominoes[j] == dominoes[j - 1]:
count += 1
else:
res += count * (count - 1) // 2
count = 1
res += count * (count - 1) // 2
return res
Result_1
Solution_2
对于递推还可以用哈希法进行优化
先设置一个字典d用于记录数组出现次数
遍历dominoes并对每个数组内进行排序
(同样时为了保证对所有能交换的数组进行累加)
如果字典中存在
则字典值(出现次数) + 1
如果不存在则新加值
最后返回res完成
Code_2
class Solution:
def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
res = 0
d = {}
for d1, d2 in dominoes:
index = tuple(sorted((d1, d2)))
if index in d:
d[index] += 1
else:
d[index] = 1
for i in d:
res += d[i] * (d[i] - 1) // 2
return res
Result_2
Solution_3
思路三是学习的官方题解
同样是对dominoes内的数组进行排序
并将其换算为一个两位数
为了避免哈希表的使用
直接用num列表记录两位数对应的val值
在记录时对相应的value值进行相加
这样就完成了累加的运算
同样是最后返回res
Code_3
class Solution:
def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
num = [0] * 100
res = 0
for x, y in dominoes:
val = (x * 10 + y if x <= y else y * 10 + x)
res += num[val]
num[val] += 1
return res