力扣日记1401

1. 题目

LeetCode 1401. 圆和矩形是否有重叠

1.1 题意

给定圆和矩形,判断两个图形是否有重叠部分

1.2 分析

两个图形重叠有两种情况,相交和包含。

先考虑相交:相交的话圆至少和矩形的某条边有交点,因为矩形四条边都平行/重合于坐标轴,所以可以求圆形和矩形的四条直线中满足情况的交点,但是矩形四条线段不是直线,交点需要判断。
简单推导一下:
( x − x 0 ) 2 + ( y − y 0 ) 2 = R 2 , ( ( x 0 , y 0 ) 为圆心 ) 与直线 x = x A 的交点: (x-x_0)^2+(y-y_0)^2=R^2,((x_0,y_0)为圆心)与直线x=x_A的交点: (xx0)2+(yy0)2=R2,((x0,y0)为圆心)与直线x=xA的交点:
( y A − y 0 ) 2 = R 2 − ( x − x 0 ) 2 (y_A-y_0)^2=R^2-(x-x_0)^2 (yAy0)2=R2(xx0)2
y A − y 0 = ± R 2 − ( x − x 0 ) 2 y_A-y_0=\pm\sqrt{R^2-(x-x_0)^2} yAy0=±R2(xx0)2
y A = y 0 ± R 2 − ( x − x 0 ) 2 y_A=y_0\pm\sqrt{R^2-(x-x_0)^2} yA=y0±R2(xx0)2
注意点细节:首先能否开根号,其次这个解出的 y A y_A yA是否在矩形的范围内

接着考虑包含:因为已经排除了相交的情况,所以此时圆和矩形不相交。有两种情况。
情况1:矩形包含圆形,此时圆心在矩形内
情况2:圆形包含矩形,此时矩形的顶点到圆心距离小于半径(或者垂直于x轴的直径的两个端点包含了矩形的y轴的范围)

1 <= radius <= 2000
-1e4 <= xCenter, yCenter <= 1e4
-1e4 <= x1 < x2 <= 1e4
-1e4 <= y1 < y2 <= 1e4

1.3 我的解法

class Solution {
public:
    double fun1(int x, int y, int r, int z){
        return y + sqrt(r * r - (z - x) * (z - x) ); 
    }
    double fun2(int x, int y, int r, int z){
        return y - sqrt(r * r - (z - x) * (z - x) );
    }
    bool checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
        if(radius * radius >= (x1 - xCenter) * (x1-xCenter) ){
            // 判断是否可以开根号
            double ya = fun1(xCenter, yCenter, radius, x1);
            double yb = fun2(xCenter, yCenter, radius, x1);
            if(ya >= y1 && ya <=y2){
                // 判断范围是否在矩形的边上
                return true;
            }
            if(yb >= y1 && yb <=y2){
                return true;
            }
        }
        if(radius * radius >= (x2 - xCenter) * (x2-xCenter) ){
            double ya = fun1(xCenter, yCenter, radius, x2);
            double yb = fun2(xCenter, yCenter, radius, x2);
            if(ya >= y1 && ya <=y2){
                return true;
            }
            if(yb >= y1 && yb <=y2){
                return true;
            }
        }
        if(radius * radius >= (y1 - yCenter) * (y1-yCenter) ){
            double xa = fun1(yCenter, xCenter, radius, y1);
            double xb = fun2(yCenter, xCenter, radius, y1);
            if(xa >= x1 && xa <=x2){
                return true;
            }
            if(xb >= x1 && xb <=x2){
                return true;
            }
        }
        if(radius * radius >= (y2 - yCenter) * (y2-yCenter) ){
            double xa = fun1(yCenter, xCenter, radius, y2);
            double xb = fun2(yCenter, xCenter, radius, y2);
            if(xa >= x1 && xa <=x2){
                return true;
            }
            if(xb >= x1 && xb <=x2){
                return true;
            }
        }
        if(xCenter>=x1 && xCenter<=x2 && yCenter>=y1 && yCenter<=y2){
            // 正方形包含圆
            // 圆心在矩形内
            return true;
        }
        if((x1 - xCenter) * (x1 - xCenter) + (y1 - yCenter) * (y1 - yCenter) <= radius * radius){
            // 圆包含正方形
            // 矩形的顶点到圆心距离小于半径
            return true;
        }
        return false;
    }
};

1.4 学习题解反思

时间复杂度O(1), 空间复杂度O(1)

因为矩形的摆放位置很特殊,所以题解中找圆心到矩形区域的最小距离,优雅。

1.5 bug日记

1.5.1 包含情况

开始就被样例的case误导,先入为主,没想到包含的情况

2. 后记

仅分享自己的想法,有意见和指点非常感谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值