一、问题描述
矩形以列表 [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
示例2
输入:rec1 = [0,0,1,1], rec2 = [1,0,2,1]
输出:false
提示:
- rect1.length == 4
- rect2.length == 4
- 109 <= rec1[i], rec2[i] <= 109
- rec1 和 rec2 表示一个面积不为零的有效矩形
二、解题方法
2.1 位置检查
果然力扣给了一个hard题,就会出一个简单题来挽回你。被拿捏了。
这个就是纯纯的数学题,对于重叠的情况,考虑起来比较复杂,可以转换一下直接考虑没有重叠的情况。
- 如果矩形 rec1 和 rec2 中至少有一个矩形的面积为 000,则一定没有重叠。即对于矩形 rec1 而言,其面积为 0当且仅当 rec1[0] == rec1[2] 或 rec1[1] == rec1[3];或者对于矩形 rec2 而言,其面积为 0 当且仅当 rec2[0] == rec2[2] 或 rec2[1] == rec2[3]。
- 当矩形 rec1 和 rec2 的面积都大于 000 时,如果我们在平面中放置一个固定的矩形 rec2,那么矩形 rec1 必须要出现在 rec2 的「四周」,也就是说,矩形 rec1 需要满足以下四种情况中的至少一种:矩形rec1在矩形rec2的左、右、上、下侧。
- 左侧:rec1[2] <= rec2[0]
- 右侧:rec1[0] >= rec2[2]
- 上侧:rec1[1] >= rec2[3]
- 下侧:rec1[3] <= rec2[1]
代码如下:
/**
* @param {number[]} rec1
* @param {number[]} rec2
* @return {boolean}
*/
var isRectangleOverlap = function(rec1, rec2) {
if(rec1[0]==rec1[2]||rec1[1]==rec1[3]||rec2[0]==rec2[2]||rec2[1]==rec2[3]){ return false;
}
if(rec1[2] <= rec2[0]||rec1[0] >= rec2[2]||rec1[1] >= rec2[3]||rec1[3] <= rec2[1]){
return false;
}
return true;
};
2.2 区域检查
这里在官方解答看到的一个解题方法,觉得很有意思,就写上来了,还有一个大佬用外切⚪之类的来解题的,我只能说简单问题复杂化,不是很支持。(我是菜鸡,不要喷我。。。。)
如果两个矩形重叠则有:两个矩形的横边之和大于横边的距离(纵边同理)。
但是需要注意的是哪个矩形在上方是未知的,所以两种情况都要考虑到,这是正向考虑的复杂所在。
/**
* @param {number[]} rec1
* @param {number[]} rec2
* @return {boolean}
*/
var isRectangleOverlap = function(rec1, rec2) {
const x1 = rec1[2] - rec1[0];
const y1 = rec1[3] - rec1[1];
const x2 = rec2[2] - rec2[0];
const y2 = rec2[3] - rec2[1];
const xDistance = Math.max(Math.abs(rec2[2] - rec1[0]), Math.abs(rec1[2] - rec2[0]));
const yDistance = Math.max(Math.abs(rec2[3] - rec1[1]), Math.abs(rec1[3] - rec2[1]));
return xDistance < x1 + x2 && yDistance < y1 + y2;
}