【数学】矩形面积

这篇博客讨论了如何计算两个边与坐标轴平行或垂直的矩形覆盖的总面积。文章提供了两种解题思路,包括原始的复杂实现和一个更简洁的优化方案。优化后的代码通过计算两个矩形的面积以及可能的重叠部分,减少了条件判断,提高了效率。博主还分享了其他更高效代码实现的观察和总结。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形,请你计算并返回两个矩形覆盖的总面积。

每个矩形由其 左下 顶点和 右上 顶点坐标表示:

第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。
第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。

解题思路

如上图所示,两个矩形可以出现的3种情况:

  1. 两个矩形相交;
  2. 两个矩形完全独立;
  3. 两个矩形是包含关系。

代码实现

按照上述代码可以有以下代码实现:


public class Solution {
    public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int v1 = (ax2 - ax1) * (ay2 - ay1);
        int v2 = (bx2 - bx1) * (by2 - by1);

        // ax1<=ax2<=bx1<=bx2
        // ay1<=ay2<=by1<=by2

        // bx1<=bx2<=ax1<=ax2
        // by1<=by2<=ay1<=ay2
        if (ax2 <= bx1 || ay2 <= by1 || bx2 <= ax1 || by2 <= ay1) {
            return v1 + v2;
        } else if (ax1 <= bx1 && bx2 <= ax2 && ay1 <= by1 && by2 <= ay2 || bx1 <= ax1 && ax2 <= bx2 && by1 <= ay1 && ay2 <= by2) {
            // ax1< bx1 < bx2< ax2
            // ay1< by1 < by2< ay2
            // bx1< ax1 < ax2< bx2
            // by1< ay1 < ay2< by2

            // 这里还要考虑部分包含的情况
            return Math.max(v1, v2);
        } else {
            return v1 + v2 - cal(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);
        }
    }

    int cal(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int x = 0;
        if (ax1 <= bx1 && bx2 <= ax2) {
            x = bx2 - bx1;
        } else if (bx1 <= ax1 && ax2 <= bx2) {
            x = ax2 - ax1;
        } else if (ax1 < bx1 && bx1 < ax2) {
            x = ax2 - bx1;
        } else if (bx1 < ax1 && ax1 < bx2) {
            x = bx2 - ax1;
        }

        int y = 0;
        if (ay1 <= by1 && by2 <= ay2) {
            y = by2 - by1;
        } else if (by1 <= ay1 && ay2 <= by2) {
            y = ay2 - ay1;
        } else if (ay1 < by1 && by1 < ay2) {
            y = ay2 - by1;
        } else if (by1 < ay1 && ay1 < by2) {
            y = by2 - ay1;
        }
        return x * y;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
//        System.out.println(solution.computeArea(-3, 0, 3, 4, 0, -1, 9, 2));
        System.out.println(solution.computeArea(-2, -2, 2, 2, -3, -3, 3, -1));
    }
}

总结

这个代码我这边实现还是很复杂的,分支特别多,整体耗时还是比较低的。看过其他代码实现,通过查看其他代码有更加简洁的实现。

思路如下:

  1. 分别求两个矩形的面积,分别是v1和v2;
  2. 求可能存在的重叠部分,
    1. int width = Math.min(ax2, bx2);
    2. int height = Math.max(ax1, ax2);
    3. 如果width > 0  并且 height > 0, 则重叠部分面积是 width * height,否则就是0;
  3. 返回v1+v2 - 重叠部分面积。

代码实现如下:


public class Solution {
    public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int v1 = (ax2 - ax1) * (ay2 - ay1);
        int v2 = (bx2 - bx1) * (by2 - by1);
        int width = Math.min(ax2, bx2) - Math.max(ax1, bx1);
        int height = Math.min(ay2, by2) - Math.max(ay1, by1);
        int overlapArea = 0;
        if (width > 0 && height > 0) {
            overlapArea = width * height;
        }
        return v1 + v2 - overlapArea;
    }


    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.computeArea(-2, -2, 2, 2, -3, -3, 3, -1));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值