力扣 leetcode 1128. 等价多米诺骨牌对的数量 (python)

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

Result_3

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值