力扣 leetcode 1128. 等價多米諾骨牌對的數量 (python)
技術標籤:pythonleetcode列表pythonleetcode演算法資料結構
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