1. 问题描述:
给你一个由一些多米诺骨牌组成的列表 dominoes。如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。形式上,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 a==c 且 b==d,或是 a==d 且 b==c。在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。
示例:
输入:dominoes = [[1,2],[2,1],[3,4],[5,6]]
输出:1
提示:
1 <= dominoes.length <= 40000
1 <= dominoes[i][j] <= 9
2. 思路分析:
一开始比较容易想到的是暴力破解,对于当前位置的列表与其后面的列表进行比较看是否相等,但是后面提交上去超时了,可能是因为后面的数据量太大了,而暴力破解的时间复杂度为O(n ^ 2),所以肯定会超时的,然后想到的是只遍历一遍dominoes列表,对列表中的元素进行计数即可,但是由于这个是一个二维的列表,所以在处理的时候我们需要将一维列表中的两个数字映射到一个位置上,因为数字都是从0-9范围的,所以可以映射为十进制的两位数,映射之后在同一个位置说明肯定是相等的,因为使用的是python语言,所以可以使用collections.defaultdict(int)来创建字典,其中字典中的值默认都是0,这样我们可以对字典中的键进行计数,最后遍历一下字典的值,计数的个数可以通过等差数列来进行计算
3. 代码如下:
字典映射:
import collections
from typing import List
class Solution:
def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
dic = collections.defaultdict(int)
for cur in dominoes:
# 对当前的数字进行映射
if cur[0] < cur[1]:
key = cur[0] * 10 + cur[1]
else:
key = cur[1] * 10 + cur[0]
dic[key] += 1
res = 0
for value in dic.values():
if value > 1:
res += value * (value - 1) // 2
return res
暴力破解:
from typing import List
class Solution:
def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
# 模拟整个过程即可
res = 0
for i in range(len(dominoes)):
for j in range(i + 1, len(dominoes)):
f = (dominoes[i][0] == dominoes[j][0] and dominoes[i][1] == dominoes[j][1]) or (
dominoes[i][0] == dominoes[j][1] and dominoes[i][1] == dominoes[j][0])
if f:
res += 1
break
return res