LeetCode.1128-等价多米诺骨牌对的数量(Number of Equivalent Domino Pairs)
这是小川的第394次更新,第428篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第259题(顺位题号是1128)。给定多米诺骨牌列表,当且仅当(a == c且b == d)或(a == d且b == c),dominoes[i] = [a,b]等价于dominoes[j] = [c,d],也就是说,一个多米诺骨牌可以旋转到等价于另一个多米诺骨牌。
返回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
02 第一种解法
暴力解法,直接使用两层循环,会超时。
public int numEquivDominoPairs(int[][] dominoes) {
int count = 0;
for (int i=0; i<dominoes.length; i++) {
for (int j=i+1; j<dominoes.length; j++) {
int a = dominoes[i][0], b = dominoes[i][1];
int c = dominoes[j][0], d = dominoes[j][1];
if ((a == c && b == d) || (a == d && b == c)) {
count++;
}
}
}
return count;
}
03 第二种解法
题目的意思是找可以配对的数组,也就是元素值相等的数组,为了降低时间复杂度,就必须将二维数组降为一维数组。
既然是值相等,那可不可以用加法或者乘法?
不行,因为加法或乘法不能保证唯一性。比如[1,6]和[2,3],做乘法后都等于6,但是这两数组明显不配对。
那我们把它变成一个两位数,较小的一个当做十位数,较大的当做个位数,这样一转换后,二维数组就变成了一维数组,此时题目也就变成了计数的问题。
因为数组元素的取值范围是[1,9],所以最大的两位数是99,最小的两位数是11,使用一个长度为100的整型数组即可。
最后遍历计数数组中的元素,计算对数,其实就是计算排列组合,有n个数,分两次取,总共有n*(n-1)种可能,但是需要去重,因为i要小于j,所以最后就是n*(n-1)/2种可能,将每次的结果累加,最后返回即可。
public int numEquivDominoPairs2(int[][] dominoes) {
int[] count = new int[100];
for (int[] temp : dominoes) {
int num = Math.min(temp[0], temp[1])*10
+ Math.max(temp[0], temp[1]);
count[num]++;
}
int result = 0;
for (int num : count) {
result += num*(num-1)/2;
}
return result;
}
04 第三种解法
和第二种解法一样的处理逻辑,只是将计数数组换成HashMap来处理。
public int numEquivDominoPairs3(int[][] dominoes) {
Map<Integer, Integer> map = new HashMap<Integer,Integer>();
for (int[] temp : dominoes) {
int num = Math.min(temp[0], temp[1])*10
+ Math.max(temp[0], temp[1]);
map.put(num, map.getOrDefault(num, 0)+1);
}
int result = 0;
for (Integer times : map.values()) {
result += times*(times-1)/2;
}
return result;
}
05 第四种解法
此解法同样利用HashMap,但是HashMap的key是字符串,先转为一个两位数,然后再转成字符串。另外,计算配对的对数也有一点不同,是用累加来算的,不算最后的n,只从1算到n-1,效果和前面用排列组合的一样。
public int numEquivDominoPairs4(int[][] dominoes) {
Map<String, Integer> map = new HashMap<String,Integer>();
int count = 0;
for (int[] temp : dominoes) {
StringBuilder sb = new StringBuilder();
sb.append(""+Math.min(temp[0], temp[1])
+ Math.max(temp[0], temp[1]));
String str = sb.toString();
if (map.containsKey(str)) {
count += map.get(str);
}
map.put(str, map.getOrDefault(str, 0)+1);
}
return count;
}
06 小结
算法专题目前已连续日更超过八个月,算法题文章265+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,在看、留言、转发就是对我最大的回报和支持!
LeetCode.1128-等价多米诺骨牌对的数量(Number of Equivalent Domino Pairs)的更多相关文章
- 【LeetCode】1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典统计 代码 复杂度分析 日期 题目地址:http ...
- 【Leetcode_easy】1128. Number of Equivalent Domino Pairs
problem 1128. Number of Equivalent Domino Pairs solution1: 不明白为什么每个元素都要加上count: class Solution { pub ...
- leetcode146周赛-5130-等价多米诺骨牌对的数量
题目描述: 方法一: class Solution(object): def numEquivDominoPairs(self, dominoes): """ :type ...
- 【leetcode】1128. Number of Equivalent Domino Pairs
题目如下: Given a list of dominoes, dominoes[i] = [a, b] is equivalent to dominoes[j] = [c, d] if and on ...
- [LeetCode] Push Dominoes 推多米诺骨牌
There are N dominoes in a line, and we place each domino vertically upright. In the beginning, we si ...
- 用1 x 2的多米诺骨牌填满M x N矩形的方案数(完美覆盖)
题意 用 $1 \times 2$ 的多米诺骨牌填满 $M \times N$ 的矩形有多少种方案,$M \leq 5,N < 2^{31}$,输出答案模 $p$. 分析 当 $M=3$时,假设 ...
- ACM - 动态规划 - P1282 多米诺骨牌
多米诺骨牌由上下 \(2\) 个方块组成,每个方块中有 \(1 \sim 6\) 个点.现有排成行的上方块中点数之和记为 \(S_1\),下方块中点数之和记为 \(S_2\),它们的差为 \(\lef ...
- 【Tsinghua OJ】多米诺骨牌(domino)问题
(domino.c/cpp)[问题描述] 小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种.她觉 得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的.现在她有n个 ...
- 省选训练赛第4场D题(多米诺骨牌)
题目来自FZU2163 多米诺骨牌 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description Vasya很喜欢排多米诺 ...
随机推荐
- python 文件操作的相对路径和绝对路径(windows)
1.相对路径 windows '.\'表示当前路径 with open(r'.\db\123.txt','w',encoding='utf-8') as f: f.write('abc') 2.绝对 ...
- linux 下 svn 重新定位 url
linux下重新定位SVN URL方法: 如果更换了SVN服务器,就需要重新定位,指向新的SVN URL. 重新定位命令:svn switch --relocate 原svn地址 新svn地址 ...
- Fetch(原生)的简单使用
前言: Fetch 提供了对 Request 和 Response 等对象通用的定义. 发送请求或者获取资源,需要使用 fetch() 方法. 具体使用代码: <script> fetch ...
- ESP8266—“ICACHE_FLASH_ATTR”宏
问:ESP8266_NONOS_SDK中ICACHE_FLASH_ATTR宏的用途是什么?我看到它取决于ICACHE_FLASH,但我不知道何时应该定义该符号.什么时候需要包括它?答:对于ESP826 ...
- 钉钉报警-prometheus-alertmanager
alertmanager alertmanager可以放在远程服务器上 报警机制 在 prometheus 中定义你的监控规则,即配置一个触发器,某个值超过了设置的阈值就触发告警, prometheu ...
- python 访问列表中的值
#!/usr/bin/python list1 = ['physics', 'chemistry', 1997, 2000] list2 = [1, 2, 3, 4, 5, 6, 7 ] print ...
- vue使用子路由时,默认的子路由视图不显示问题
解决办法是,将父级的name去掉.(大多数情况下是按name来跳转的,不过这样一改,调到父级就得用路径跳转了): 下面上一下路由的配置: { path: "/index", com ...
- sqoop数据导出
1.将oracle的jdbc的jar包copy到sqoop的lib目录下 2. sqoop export --connect jdbc:oracle:thin:@XXXXX:1521:TMDM --u ...
- TCP输入 之 tcp_queue_rcv
tcp_queue_rcv用于将接收到的skb加入到接收队列receive_queue中,首先会调用tcp_try_coalesce进行分段合并到队列中最后一个skb的尝试,若失败则调用__skb_q ...
- JDBC——数据库连接池以及JDBC代码模版模版
该代码模版由三部分组成,一个是数据库连接池,一个是数据库常用操作的模版抽象,还有一个是重写的连接对象,主要重写关闭连接的方法,将其改为释放到连接池. OolongConnectionPool.java ...