836.矩形重叠

  1. 836.矩形重叠
    1. 836.1 题目
    2. 836.2 题解
      1. 区间投影法
      2. 边界判断法
    3. 836.3 代码
    4. 836.4 运行结果

836.矩形重叠


836.1 题目

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

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

给出两个矩形 rec1rec2。如果它们重叠,返回 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

示例 3:

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

提示:

  • rect1.length == 4
  • rect2.length == 4
  • -10^9 <= rec1[i], rec2[i] <= 10^9
  • rec1rec2 表示一个面积不为零的有效矩形

836.2 题解

区间投影法

// 方法一:区间投影法
// 检查两个矩形在x和y的投影是否相交,通过比较最大起点是否小于最小终点判断
static bool IsRectangleOverlap1(int[] rec1, int[] rec2)
{
    // 检查 x 轴投影是否相交
    bool xOverlap = CheckOverlap(rec1[0], rec1[2], rec2[0], rec2[2]);
    // 检查 y 轴投影是否相交
    bool yOverlap = CheckOverlap(rec1[1], rec1[3], rec2[1], rec2[3]);
    // 如果 x 轴和 y 轴投影都相交,则矩形重叠
    return xOverlap && yOverlap;
}

// 检查投影是否相交
static bool CheckOverlap(int start1, int end1, int start2, int end2)
{
    // 通过比较最大起点和最小终点来检查两个区间在数轴上是否有重叠
    return Math.Max(start1, start2) < Math.Min(end1, end2);
}

边界判断法

// 方法二:边界判断法
// 判断矩形1是否在矩形2的左侧、右侧、上方和下方,如果都不在说明重叠
static bool IsRectangleOverlap2(int[] rec1, int[] rec2)
{
    // 检查 rec1 在 rec2 的左侧、右侧、上方和下方
    bool isLeft = rec1[2] <= rec2[0];
    bool isRight = rec1[0] >= rec2[2];
    bool isAbove = rec1[1] >= rec2[3];
    bool isBelow = rec1[3] <= rec2[1];

    // 如果都不在说明重叠
    return !(isLeft || isRight || isAbove || isBelow);
}

836.3 代码

using System;

class Program
{
    static void Main()
    {
        #region 题目

        // 矩形以列表 [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

        // 示例 3:
        // 输入:rec1 = [0,0,1,1], rec2 = [2,2,3,3]
        // 输出:false

        // 提示:
        // rect1.length == 4
        // rect2.length == 4
        // -109 <= rec1[i], rec2[i] <= 109
        // rec1 和 rec2 表示一个面积不为零的有效矩形

        #endregion

        #region 测试

        // 示例 1
        int[] rec1_1 = { 0, 0, 2, 2 };
        int[] rec2_1 = { 1, 1, 3, 3 };
        bool result1_1 = IsRectangleOverlap1(rec1_1, rec2_1);
        Console.WriteLine($"示例1 方法1 输出:{result1_1}");
        bool result1_2 = IsRectangleOverlap2(rec1_1, rec2_1);
        Console.WriteLine($"示例1 方法2 输出:{result1_2}");

        // 示例 2
        int[] rec1_2 = { 0, 0, 1, 1 };
        int[] rec2_2 = { 1, 0, 2, 1 };
        bool result2_1 = IsRectangleOverlap1(rec1_2, rec2_2);
        Console.WriteLine($"示例2 方法1 输出:{result2_1}");
        bool result2_2 = IsRectangleOverlap2(rec1_2, rec2_2);
        Console.WriteLine($"示例2 方法2 输出:{result2_2}");

        // 示例 3
        int[] rec1_3 = { 0, 0, 1, 1 };
        int[] rec2_3 = { 2, 2, 3, 3 };
        bool result3_1 = IsRectangleOverlap1(rec1_3, rec2_3);
        Console.WriteLine($"示例3 方法1 输出:{result3_1}");
        bool result3_2 = IsRectangleOverlap2(rec1_3, rec2_3);
        Console.WriteLine($"示例3 方法2 输出:{result3_2}");

        #endregion
    }

    #region 答案

    // 方法一:区间投影法
    // 检查两个矩形在x和y的投影是否相交,通过比较最大起点是否小于最小终点判断
    static bool IsRectangleOverlap1(int[] rec1, int[] rec2)
    {
        // 检查 x 轴投影是否相交
        bool xOverlap = CheckOverlap(rec1[0], rec1[2], rec2[0], rec2[2]);
        // 检查 y 轴投影是否相交
        bool yOverlap = CheckOverlap(rec1[1], rec1[3], rec2[1], rec2[3]);
        // 如果 x 轴和 y 轴投影都相交,则矩形重叠
        return xOverlap && yOverlap;
    }

    // 检查投影是否相交
    static bool CheckOverlap(int start1, int end1, int start2, int end2)
    {
        // 通过比较最大起点和最小终点来检查两个区间在数轴上是否有重叠
        return Math.Max(start1, start2) < Math.Min(end1, end2);
    }

    // 方法二:边界判断法
    // 判断矩形1是否在矩形2的左侧、右侧、上方和下方,如果都不在说明重叠
    static bool IsRectangleOverlap2(int[] rec1, int[] rec2)
    {
        // 检查 rec1 在 rec2 的左侧、右侧、上方和下方
        bool isLeft = rec1[2] <= rec2[0];
        bool isRight = rec1[0] >= rec2[2];
        bool isAbove = rec1[1] >= rec2[3];
        bool isBelow = rec1[3] <= rec2[1];

        // 如果都不在说明重叠
        return !(isLeft || isRight || isAbove || isBelow);
    }

    #endregion
}

836.4 运行结果

示例1 方法1 输出:True
示例1 方法2 输出:True
示例2 方法1 输出:False
示例2 方法2 输出:False
示例3 方法1 输出:False
示例3 方法2 输出:False


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏