题目描述
思路
- 法一(哈希):把每个domino都转换成一个对象,该对象重写了hashCode和equals方法,当两个domino的两个数一样时认为这两个domino相等(tips:hashCode的结果也应该满足该条件)。遍历一遍计下每个domino出现的次数为count,然后将每个count*(count-1)/2相加即为最终结果。
- 法二(二维转一维):观察到dominoes[i][j]为1到9之间的数。可以直接将domino转化为一个100以内的整数,这个整数的十位为domino中较大数,个位为domino中较小数。遍历一遍该数组,进行转化的同时使用一个int[100]数组记录每个数出现的次数count。最终将每个count*(count-1)/2相加即为最终结果。
哈希
java代码如下
import java.util.HashMap;
import java.util.Map;
class Solution {
class Domino {
int a;
int b;
public Domino(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public int hashCode() {
int hash = 17;
hash = (hash + a * 31 + b * 31) * 31;
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Domino) {
Domino s = (Domino) obj;
if ((s.a == this.a && s.b == this.b) || (s.a == this.b && s.b == this.a)) {
return true;
} else {
return false;
}
}
return super.equals(obj);
}
}
public int numEquivDominoPairs(int[][] dominoes) {
int length = dominoes.length;
int res = 0;
Map<Domino, Integer> repeatMap = new HashMap<>();
Map<Integer, Integer> countMap = new HashMap<>();
for (int i = 0; i < length; i++) {
Domino domino = new Domino(dominoes[i][0], dominoes[i][1]);
if (repeatMap.containsKey(domino)) {
int value = repeatMap.get(domino) + 1;
repeatMap.put(domino, value);
} else {
repeatMap.put(domino, 1);
}
}
for (Integer value : repeatMap.values()) {
if (value > 1) {
if (countMap.containsKey(value)) {
res += countMap.get(value);
} else {
countMap.put(value, value * (value - 1) / 2);
res += countMap.get(value);
}
}
}
return res;
}
}
执行用时:13 ms, 在所有 Java 提交中击败了26.33%的用户
内存消耗:47.2 MB, 在所有 Java 提交中击败了96.09%的用户
结果不好,如果题目没有说明1 <= dominoes[i][j] <= 9的话结果应该是挺不错的。但是在这一条件下,有更好的方法。
二维转一维
java代码如下
class Solution {
public int numEquivDominoPairs(int[][] dominoes) {
int[] counts = new int[100];
int length = dominoes.length;
int res = 0;
for (int i = 0; i < length; i++) {
int num = transform(dominoes[i]);
counts[num]++;
}
for (int i = 0; i < 100; i++) {
int count = counts[i];
if (count > 1) {
res += count * (count - 1) / 2;
}
}
return res;
}
public int transform(int[] nums) {
int a = nums[0];
int b = nums[1];
int res = a > b ? a * 10 + b : b * 10 + a;
return res;
}
}
执行用时:2 ms, 在所有 Java 提交中击败了97.76%的用户
内存消耗:48 MB, 在所有 Java 提交中击败了9.46%的用户
ojbk