【LeetCode】1128. Number of Equivalent Domino Pairs 等價多米諾骨牌對的數量(Easy)(JAVA)每日一題
技術標籤:LeetCode 每日一題leetcodejava演算法資料結構面試
【LeetCode】1128. Number of Equivalent Domino Pairs 等價多米諾骨牌對的數量(Easy)(JAVA)
題目地址: https://leetcode.com/problems/number-of-equivalent-domino-pairs/
題目描述:
Given a list of dominoes, dominoes[i] = [a, b] is equivalent to dominoes[j] = [c, d] if and only if either (a == c and b == d), or (a == d and b == c) - that is, one domino can be rotated to be equal to another domino.
Return the number of pairs (i, j) for which 0 <= i < j < dominoes.length, and dominoes[i] is equivalent to dominoes[j].
Example 1:
Input: dominoes = [[1,2],[2,1],[3,4],[5,6]]
Output: 1
Constraints:
- 1 <= dominoes.length <= 40000
- 1 <= dominoes[i][j] <= 9
題目大意
給你一個由一些多米諾骨牌組成的列表 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) 的數量。
解題方法
暴力迴圈
- 直接用暴力雙重迴圈,時間複雜度 O(n^2)
- 直接超時
class Solution { public int numEquivDominoPairs(int[][] dominoes) { int res = 0; for (int i = 0; i < dominoes.length; i++) { for (int j = i + 1; j < dominoes.length; j++) { if (dominoes[i][0] == dominoes[j][0] && dominoes[i][1] == dominoes[j][1]) { res++; } else if (dominoes[i][0] == dominoes[j][1] && dominoes[i][1] == dominoes[j][0]) { res++; } } } return res; } }
超出時間限制
優化一
- 對陣列先進行排序,時間複雜度 O(nlogn)
- 再找出重複的
class Solution {
public int numEquivDominoPairs(int[][] dominoes) {
for (int i = 0; i < dominoes.length; i++) {
if (dominoes[i][0] <= dominoes[i][1]) continue;
int temp = dominoes[i][0];
dominoes[i][0] = dominoes[i][1];
dominoes[i][1] = temp;
}
Arrays.sort(dominoes, (a, b) -> (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));
int res = 0;
for (int i = 0; i < dominoes.length; i++) {
int next = i + 1;
while (next < dominoes.length && dominoes[i][0] == dominoes[next][0] && dominoes[i][1] == dominoes[next][1]) {
next++;
}
int len = next - i;
res += len * (len - 1) / 2;
i = next - 1;
}
return res;
}
}
執行耗時:15 ms,擊敗了23.27% 的Java使用者
記憶體消耗:47.7 MB,擊敗了35.18% 的Java使用者
優化二
- 因為 1 <= dominoes[i][j] <= 9, 可以用一個 y = 10 * x + z 來表示 dominoes[i] 整體的值
- 用一個數組來儲存即可,時間複雜度 O(n)
- note: 因為這裡總共才 100 個數,用陣列來存可以更快,Map 消耗空間大而且存取速度慢; x 和 z 可以交換位置,所以 x 代表較小的數,z 代表較大的數
class Solution {
public int numEquivDominoPairs(int[][] dominoes) {
int[] num = new int[100];
int ret = 0;
for (int[] domino : dominoes) {
int val = domino[0] < domino[1] ? domino[0] * 10 + domino[1] : domino[1] * 10 + domino[0];
ret += num[val];
num[val]++;
}
return ret;
}
}
執行耗時:3 ms,擊敗了85.51% 的Java使用者
記憶體消耗:47.6 MB,擊敗了51.03% 的Java使用者