开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
题目:
给你一个由一些多米诺骨牌组成的列表 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 <= 400001 <= dominoes[i][j] <= 9
🙇♂️ 感想:题目也是很清晰明了,找到相等的对,牌可以翻转。如果不考虑时间复杂度,上来就搞一个嵌套循环就搞定了。可惜题目有时间限制,可想而知超时了 🤣。那如何降低时间复杂度呢。
🙇♂️ 解题思路:可以使用哈希表将数值先循环遍历格式化一遍,将相同的值存到一起。使用一个map进行存值,key记得先转换为值类型存储,不然每次存进去的都不是相等的。如果map中存在该值,则该值+1即可,如果没有将值翻转过来判断是否存在,如果存在则,翻转值+1即可。如果都没有,则将值插入,并赋值为1即可。根据自己推到也不难推出,与斐波那契数列的差不多即:(n * (n - 1) )/ 2
function numEquivDominoPairs(dominoes: number[][]): number {
let result: number = 0
let map = new Map()
for (let i = 0; i < dominoes.length; i++) {
let str = dominoes[i].toString()
if (map.has(str)) {
let num = map.get(str)
map.set(str, ++num)
} else {
let [m,n] = dominoes[i]
if (map.has([n, m].toString())) {
let num = map.get([n, m].toString())
map.set([n, m].toString(), ++num)
} else {
map.set(str, 1)
}
}
}
for (let [key, value] of map.entries()) {
if (value > 1) {
result += (value * (value - 1)) /2
}
}
return result
};