这是我对this问题的解决方案:
给出一个表示为(半径,x_center,y_center)的圆和一个 轴对齐的矩形表示为(x1,y1,x2,y2),其中(x1,y1) 是左下角的坐标,而(x2,y2)是 矩形右上角的坐标。
如果圆形和矩形重叠,则返回True 返回False。
换句话说,检查是否存在任何点(xi,yi)使得 同时属于圆形和矩形。
class Solution {
public boolean checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
for(int i=x1; i<=x2; ){
for(int j=y1; j<=y2; ){
System.out.println((Math.pow(i-x_center, 2) +" "+ Math.pow(j-y_center, 2))+" "+Math.pow(radius, 2));
System.out.println(i+" "+j);
if((Math.pow(i-x_center, 2)+Math.pow(j-y_center, 2))<=Math.pow(radius, 2)){
return true;
}
j += 1;
}
i += 1;
}
return false;
}
}
我非常相信逻辑是正确的。从矩形的左下角到右上角,对于每个点,我都在检查它是否位于圆内。 如果我将增量步长增加到超过“ 1”的任何值,我会发现代码对于矩形和圆形只是彼此“接触”的测试用例失败。但是在某些情况下,以这种方式进行操作会导致超过时间限制。如何为此逻辑优化代码?
谢谢。
答案 0 :(得分:1)
此问题可以简化。我找到了时间复杂度O(1)和内存复杂度O(1)的解决方案。不必检查矩形中的每个像素,您甚至可以只考虑边界本身。
我认为有3种情况:
我将圆心称为x0和y0。
您可以简单地选中圆的边界框,例如,它是圆的最北点(x0,y0-radius),它是圆的最南点(x0, y0 + radius),最东端(x0-radius,y0)和最西端(x0 + radius,y0)。如果它们都落在矩形内,那么问题就解决了。
如果矩形完全在圆内,则绝对意味着其角到圆心的距离小于半径。只需检查每个角的距离即可。
现在困难的部分了。
编辑:同样,您的代码在几乎接触不到的测试中失败的原因可能是浮点错误。 not 不要使用==(或者在这种情况下为<=,这是相似的)来检查两个浮点(甚至是浮点和整数)值是否相同。 Java中的Math.pow()返回double。只需使用普通乘法进行平方即可。 实际上,您可能想尽可能地远离浮点,除非您不知道如何摆脱它们,并且问题说“ 0.001错误是可以接受的”或类似的说法。它们既缓慢又容易出错。
编辑2:另外,我已经编写了代码以帮助您帮助理解这一解释。我已经在站点上对其进行了测试,它适用于运行时间为1ms,内存使用率为37.7Mb的每个测试。
class Solution {
public boolean checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
//case 1: circle is fully inside rectangle
//check the bounding box of the circle against the rectangle
if(x_center-radius>=x1&&y_center-radius>=y1
&&x_center+radius<=x2&&y_center+radius<=y2
)
return true;
//case 2: checking closest corner against circle bounds
int minX=(Math.abs(x_center-x1)>Math.abs(x_center-x2))?(x_center-x2):(x_center-x1);
int minY=(Math.abs(y_center-y1)>Math.abs(y_center-y2))?(y_center-y2):(y_center-y1);
if(minX*minX+minY*minY<=radius*radius)
return true;
//case 3: checking distances to segments against circle bounds
//Checking distance from a segment to a point is alike checking
//the distance from the line the segment is part of to a point,
//except you have to check if the closest point from the segment
//is actually on the segment. If it isn't, the distance from a
//segment to a point is the minimum distance from one of its
//corners to the point.
if(x1<=x_center&&x_center<=x2)
if(minY*minY<=radius*radius)
return true;
if(y1<=y_center&&y_center<=y2)
if(minX*minX<=radius*radius)
return true;
return false;
}
}
此代码可能会缩短。但是,从时间复杂度的角度来看,它不会比O(1)更好。