列表

详情


2001. 可互换矩形的组数

用一个下标从 0 开始的二维整数数组 rectangles 来表示 n 个矩形,其中 rectangles[i] = [widthi, heighti] 表示第 i 个矩形的宽度和高度。

如果两个矩形 iji < j)的宽高比相同,则认为这两个矩形 可互换 。更规范的说法是,两个矩形满足 widthi/heighti == widthj/heightj(使用实数除法而非整数除法),则认为这两个矩形 可互换

计算并返回 rectangles 中有多少对 可互换 矩形。

 

示例 1:

输入:rectangles = [[4,8],[3,6],[10,20],[15,30]]
输出:6
解释:下面按下标(从 0 开始)列出可互换矩形的配对情况:
- 矩形 0 和矩形 1 :4/8 == 3/6
- 矩形 0 和矩形 2 :4/8 == 10/20
- 矩形 0 和矩形 3 :4/8 == 15/30
- 矩形 1 和矩形 2 :3/6 == 10/20
- 矩形 1 和矩形 3 :3/6 == 15/30
- 矩形 2 和矩形 3 :10/20 == 15/30

示例 2:

输入:rectangles = [[4,5],[7,8]]
输出:0
解释:不存在成对的可互换矩形。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: long long interchangeableRectangles(vector<vector<int>>& rectangles) { } };

php 解法, 执行用时: 636 ms, 内存消耗: 142.3 MB, 提交时间: 2023-09-14 01:08:07

class Solution {
    /**
     * @param Integer[][] $rectangles
     * @return Integer
     */
    function interchangeableRectangles($rectangles) {
        $total = 0;
        //获取相同倍数的数字
        foreach($rectangles as $value){
            $key = $value[1]/$value[0];
            $key = (string)$key;
            $arr[$key]++;
            //每遇到相同倍数的就添加组合倍数
            $total = $total + ($arr[$key]-1);
        }
        return $total;
    }
}

python3 解法, 执行用时: 200 ms, 内存消耗: 60.6 MB, 提交时间: 2023-09-14 01:07:16

class Solution:
    def interchangeableRectangles(self, rectangles: List[List[int]]) -> int:
        from math import gcd
        n = len(rectangles)
        d = {}
        cnt = 0
        for w, h in rectangles:
            _gcd = gcd(w, h)
            key = (w // _gcd, h // _gcd)
            if key in d:
                cnt += d[key]
                d[key] += 1
            else:
                d[key] = 1
        return cnt
        # return sum(1 for i in range(n) for j in range(i + 1, n) 
        #     if rectangles[i][0] * rectangles[j][1] == rectangles[i][1] * rectangles[j][0])

cpp 解法, 执行用时: 368 ms, 内存消耗: 137.5 MB, 提交时间: 2023-09-14 01:06:50

class Solution {
public:
    using LL = long long;

    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    LL interchangeableRectangles(vector<vector<int>>& rectangles) {
        unordered_map<LL, LL> map;
        constexpr LL BASE = (LL)1e8;

        for (auto& p : rectangles) {
            int x = p[0], y = p[1];
            int div = gcd(x, y);
            // 使用十进制压缩 [x, y]
            LL frac = (x / div) * BASE + (y / div);
            map[frac]++;
        }

        LL res = 0L;
        for (auto& [k, v] : map) {
            res += v * (v - 1) / 2;
        }

        return res;
    }
};

java 解法, 执行用时: 55 ms, 内存消耗: 89.8 MB, 提交时间: 2023-09-14 01:06:25

class Solution {
    private int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    public long interchangeableRectangles(int[][] arr) {
        Map<Long, Long> map = new HashMap<>();
        final long BASE = (long)1e8;
        
        for (var p : arr) {
            int a = p[0], b = p[1];
            int div = gcd(a, b);
            // String frac = (a / div) + "/" + (b / div);
            // 使用数字压缩 [x, y] 比较快
            long frac = (a / div) * BASE + (b / div);
            map.put(frac, map.getOrDefault(frac, 0L) + 1);
        }
        
        long sum = 0L;
        for (var x : map.values()) {
            sum += x * (x - 1) / 2;
        }
        
        return sum;
    }
}

golang 解法, 执行用时: 268 ms, 内存消耗: 19.8 MB, 提交时间: 2023-09-14 01:05:35

func interchangeableRectangles(rectangles [][]int) (ans int64) {
	cnt := map[[2]int]int64{}
	for _, p := range rectangles {
		// 计算 w/h 的最简分数,计入哈希表
		w, h := p[0], p[1]
		g := gcd(w, h)
		cnt[[2]int{w / g, h / g}]++
	}
	for _, m := range cnt {
		ans += m * (m - 1) / 2
	}
	return
}

func gcd(a, b int) int {
	for a != 0 {
		a, b = b%a, a
	}
	return b
}

rust 解法, 执行用时: 60 ms, 内存消耗: 11.5 MB, 提交时间: 2023-09-14 01:05:15

use std::collections::HashMap;
impl Solution {
    pub fn interchangeable_rectangles(rectangles: Vec<Vec<i32>>) -> i64 {
        fn simplify(m0: i32, n0: i32) -> (i32, i32) {
            let (mut m, mut n) = if m0 > n0 { (m0, n0) } else { (n0, m0) };
            let mut r = m % n;
            while r != 0 {
                m = n;
                n = r;
                r = m % n;
            }
            (m0 / n, n0 / n)
        }
        let mut m: HashMap<(i32, i32), i64> = HashMap::new();
        for r in rectangles {
            let pair = simplify(r[0], r[1]);
            *m.entry(pair).or_default() += 1;
        }
        m.values()
            .filter(|&n| n >= &2)
            .map(|&n| n * (n - 1) / 2)
            .sum()
    }

    // 解法二
    pub fn interchangeable_rectangles2(rectangles: Vec<Vec<i32>>) -> i64 {
        //采用最大公约数算法,把tuple 作为key
        let mut map: HashMap<(i32, i32), i64> = HashMap::new();
        for item in rectangles {
            let gcd = Self::gcd(item[0], item[1]);
            let count = map.entry((item[0] / gcd, item[1] / gcd)).or_insert(0);
            *count += 1;
        }
        let mut res: i64 = 0;
        for val in map.values() {
            res += Self::acm(*val);
        }
        res
    }
    
    //累加
    pub fn acm(num: i64) -> i64 {
        num as i64 * (num as i64 - 1) / 2
    }
    
    //求最大公约数
    pub fn gcd(mut m: i32, mut n: i32) -> i32 {
        while n > 0 {
            let temp = n;
            n = m % n;
            m = temp;
        }
        m
    }
}

上一题