等价多米诺骨牌对的数量
等价多米诺骨牌对的数量
LeetCode 第 146场周赛
题目
给你一个由一些多米诺骨牌组成的列表 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
解题思路
- 本题对算法复杂度的要求较高,使用暴力的方式用时太大
- 利用
HashMap
的特性来优化算法的复杂度 - 改变
数字对
内两个数字的顺序不会影响最终结果,所以将所有多米诺骨牌 数值均改成 从小到大的顺序 - 一级map的
key1
为数字对
第一位的值,value1
为二级map - 二级map的
key2
为数字对
第二位的值,value2
为该数字对的出现次数 - 例如
[[1,2],[2,1],[3,4],[5,6]]
存储进Map之后的值为
key1 | key2 | value2 |
---|---|---|
1 | 2 | 2 |
3 | 4 | 1 |
5 | 6 | 1 |
- 当往
map
中插入数值时,若已存在(即value2
的值为>=1
的数值)便将总数sum
加上value2
的值,再将value2的值+1
- 若不存在,则创建,并将value2的值初始化为
1
代码(Java)
class Solution {
public int numEquivDominoPairs(int[][] dominoes) {
//初始化Map集合
HashMap<Integer, HashMap<Integer, Integer>> map = new HashMap<>();
//定义总数sum,并初始化为0
int sum = 0;
//循环遍历二维数组dominoes
for (int i = 0; i < dominoes.length ; i++) {
//获取当前「数字对」的值,并将较小的值设置为a,较大的值设置为b
Integer a = dominoes[i][0];
Integer b = dominoes[i][1];
if (a > b) {
a = dominoes[i][1];
b = dominoes[i][0];
}
//将a 作为Map1的key1
//而b 作为Map1的value1 (即map2) 的key2
//判断Map1中是否有key1 为 a 的值
if (map.containsKey(a)) {
HashMap<Integer, Integer> list = map.get(a);
//判断Map2中是否有key2 为 b 的值
if (list.containsKey(b)) {
//获取value2的值并加入到sum中
int count = list.get(b);
sum = sum + count;
//对应的value的值+1
list.put(b, count+1);
map.put(a, list);
} else {
//初始化数值为1
list.put(b, 1);
map.put(a, list);
}
} else {
//初始化数值为1
HashMap<Integer, Integer> list = new HashMap<>();
list.put(b, 1);
map.put(a, list);
}
}
return sum;
}
}