【拒绝算法PUA】0x01- 区间比较技巧

判断两个线段是否相交

判断两线段是否存在交集,这里吧线段包含关系也判断为相交,具体可以分为以下四种场景,分别用图表示:

场景一

两线段起点重合,终点不重合。
在这里插入图片描述

(minA >= minB) && (maxA < maxB)

场景二

两线段终点重合,起点不重合。
在这里插入图片描述

(minA > minB) && (maxA <= end)

场景三

起点终点都各不重合,存在包含关系,且A线段比B线段长。
在这里插入图片描述

(minA <= minB) && (maxA >= maxB)

场景四

起点终点都各不重合,存在包含关系,且A线段比B线段短。
在这里插入图片描述

(minA >= minB) && (maxA <= maxB)

总结

可以抽取公共方法。

  • 返回值是这四种情况之一,即可判断两线段有交集。
return (minA >= minB) && (maxA < maxB) || (minA > minB) && (maxA <= end) 
|| (minA <= minB) && (maxA >= maxB) || (minA >= minB) && (maxA <= maxB);
  • 更简单的方法:

不重合的情况示意

在这里插入图片描述
两线段不重合的情况取反代码如下:

return !(maxA < minB || maxB < minA)

判断两个矩形是否相交

两个矩形是否相交?
第一矩形:(x1, y1)(x2, y2)
第二矩形:(x3, y3)(x4, y4)

矩形重叠场景分析

  • 枚举几种场景(不全)

可以看到情况非常复杂,不容易枚举覆盖所有场景。 (舍弃)
在这里插入图片描述

降维方法

矩形投影到坐标轴上,就变成了线段区间。两个互相重叠的矩形,在 x 轴和 y 轴上投影的区间也是重叠的。因此,可以将矩形重叠问题转化成了区间重叠问题,将二维空间问题转换为平面问题。

在这里插入图片描述

结合前文所述,平面线段重合场景有四种,不重合场景有两种,因此我们可以分别针对x轴和y轴坐标组成的两组线段做重叠判断。

再次引用前文两个线段不重合的场景,并稍作转换如下图所示:
在这里插入图片描述

经过分析,可以知道区间不重叠的条件:e1 <= s2 || e2 <= s1。将条件取反即为区间重叠的条件。

总结

通过对角线上的两个点就可以表示一个矩阵,因此矩阵重叠的判断,可以抽象成对四个点坐标的比较,可以比较横坐标X或者纵坐标Y

此处,我们以横坐标比较为例,做出如下判别总结:

// 矩阵1的右边界 <= 矩阵2的左边界 || 矩阵2的右边界 <= 矩阵2的左边界
boolean xOverlap = !(x2 <= x3 || x4 <= x1);

// 矩阵1的上边界 <= 矩阵2的下边界 || 矩阵1的下边界 >= 矩阵2的上边界
boolean yOverlap = !(y2 <= y3 || y1 >= y4);

return xOverlap && yOverlap;

OJ练习

Leetcode: 836. 矩形重叠

矩形以列表 [x1, y1, x2, y2] 的形式表示,其中 (x1, y1) 为左下角的坐标,(x2, y2) 是右上角的坐标。矩形的上下边平行于 x 轴,左右边平行于 y 轴。

如果相交的面积为 正 ,则称两矩形重叠。需要明确的是,只在角或边接触的两个矩形不构成重叠。

给出两个矩形 rec1 rec2 。如果它们重叠,返回 true;否则,返回 false

示例 1:

输入:rec1 = [0,0,2,2], rec2 = [1,1,3,3]
输出:true


在这里插入图片描述

class Solution {
public:
    bool isRectangleOverlap(vector<int>& rec1, vector<int>& rec2) {
     int x1 = rec1[0];
     int y1 = rec1[1];
     int x2 = rec1[2];
     int y2 = rec1[3];

     int x3 = rec2[0];
     int y3 = rec2[1];
     int x4 = rec2[2];
     int y4 = rec2[3];
     // 矩阵1的右边界 < 矩阵2的左边界 || 矩阵2的右边界 < 矩阵2的左边界
     bool xOverlap = !(x2 <= x3 || x4 <= x1);

     // 矩阵1的上边界 < 矩阵2的下边界 || 矩阵1的下边界 > 矩阵2的上边界
     bool yOverlap = !(y2 <= y3 || y1 >= y4);
     return xOverlap && yOverlap;
     }
};

参考资料

  1. https://blog.csdn.net/LLM1602/article/details/104977945
  2. https://blog.csdn.net/qq_41605114/article/details/106718697
  3. https://leetcode.cn/problems/rectangle-overlap/solutions/1/tu-jie-jiang-ju-xing-zhong-die-wen-ti-zhuan-hua-we/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值