等价多米诺骨牌对的数量
等价多米诺骨牌对的数量
等价多米诺骨牌对的数量
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;
}
}
查看8道真题和解析