1. 程式人生 > 其它 >【LeetCode】1128. Number of Equivalent Domino Pairs 等價多米諾骨牌對的數量(Easy)(JAVA)每日一題

【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) 的數量。

解題方法

暴力迴圈

  1. 直接用暴力雙重迴圈,時間複雜度 O(n^2)
  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;
    }
}

超出時間限制

優化一

  1. 對陣列先進行排序,時間複雜度 O(nlogn)
  2. 再找出重複的
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. 因為 1 <= dominoes[i][j] <= 9, 可以用一個 y = 10 * x + z 來表示 dominoes[i] 整體的值
  2. 用一個數組來儲存即可,時間複雜度 O(n)
  3. 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使用者

歡迎關注我的公眾號,LeetCode 每日一題更新