leetcode-等价多米诺骨牌对的数量

 题目来自LeetCode,链接:number-of-equivalent-domino-pairs。具体描述为:给你一个由一些多米诺骨牌组成的列表 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 <= dominoes.length <= 40000
  • 1 <= dominoes[i][j] <= 9

 示例:

输入:dominoes = [[1,2],[2,1],[3,4],[5,6]]
输出:1

 一个很容易想到的思路就是用每个骨牌对做key,出现次数做value,最后的value假设为n,那么 C n 2 C_{n}^{2} 就是此骨牌对的数量。当然,数组是做不了key的,一开始不知道这些数组都是长度为2所以先转了字符串,后来才发现数组长度都是2,那么就容易多了,直接转成一个两位数即可,不过由于可以逆序,所以需要约定生成的时候小数在前大数在后,比如[1,2]->12,[2,1]->12。又考虑到这里数字的大小不会超过100,所以可以不用字典/Map,直接用一个100长度的数组保存value(实际可能的数字只有45种,可以进一步减少空间需求的)。

 计算骨牌对数的时候可以计算所有的 C n 2 C_{n}^{2} 之和,但也可以在遍历过程中直接累加出来,这可以通过 C n + 1 2 C n 2 = n C_{n+1}^{2}-C_{n}^{2}=n 看出来,遍历过程只要当前数组已经出现过,就将统计次数加上之前的次数,然后出现次数再+1。总的时间复杂度为 O ( N ) O(N) ,空间复杂度为 O ( 1 ) O(1)

 JAVA版代码如下:

class Solution {
    public int numEquivDominoPairs(int[][] dominoes) {
        int count = 0, key;
        int[] record = new int[100];
        for (int[] pair : dominoes) {
            if (pair[0] < pair[1]) {
                key = pair[0] * 10 + pair[1];
            }
            else {
                key = pair[1] * 10 + pair[0];
            }
            count += record[key]++;
        }
        return count;
    }
}

 提交结果如下:


 Python版代码如下:

class Solution:
    def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
        recordLst = [0 for i in range(100)]     #数字最大为99
        count = 0
        for x, y in dominoes:
            key = min(x, y) * 10 + max(x, y)    #[1,2]->12, [2,1]->12
            count += recordLst[key]             #(n+1)n/2-n(n-1)/2=n
            recordLst[key] += 1
        return count

 提交结果如下:


发布了19 篇原创文章 · 获赞 6 · 访问量 6328

猜你喜欢

转载自blog.csdn.net/JR_Chan/article/details/104633514