Java 如何优化此解决方案以避免超过时间限制?

Java 如何优化此解决方案以避免超过时间限制?,java,algorithm,optimization,Java,Algorithm,Optimization,这是我对问题的解答: 给定一个表示为(半径、x_中心、y_中心)和 轴对齐矩形,表示为(x1,y1,x2,y2),其中(x1,y1) 是左下角的坐标,(x2,y2)是 矩形右上角的坐标 如果圆和矩形重叠,则返回True,否则返回True 返回False 换句话说,检查是否有任何点(xi,yi)可以 同时属于圆形和矩形 类解决方案{ 公共布尔校验重叠(整数半径、整数x_中心、整数y_中心、整数x1、整数y1、整数x2、整数y2){ 对于(int i=x1;i这个问题可以简化。我找到了时间复杂度O(

这是我对问题的解答:

给定一个表示为(半径、x_中心、y_中心)和 轴对齐矩形,表示为(x1,y1,x2,y2),其中(x1,y1) 是左下角的坐标,(x2,y2)是 矩形右上角的坐标

如果圆和矩形重叠,则返回True,否则返回True 返回False

换句话说,检查是否有任何点(xi,yi)可以 同时属于圆形和矩形

类解决方案{
公共布尔校验重叠(整数半径、整数x_中心、整数y_中心、整数x1、整数y1、整数x2、整数y2){

对于(int i=x1;i这个问题可以简化。我找到了时间复杂度O(1)和内存复杂度O(1)的解决方案。您甚至可以只考虑边界本身,而不是检查矩形中的每个像素

在我看来,有三种情况:

  • 圆完全位于矩形内
  • 矩形完全在圆内
  • 圆形和矩形轮廓至少在一个点上相交。这是比较难的一个
  • 我将调用圆心坐标x0和y0

  • 您只需检查圆的边界框,如中所示,它是圆的最北端点(x0,y0半径),它是圆的最南端点(x0,y0+半径),最东端点(x0半径,y0)和最西端点(x0+半径,y0)。如果它们都在矩形内,则问题得到解决

  • 如果一个矩形完全在一个圆内,这肯定意味着它的角点与圆中心的距离小于半径。只需检查每个角点的距离

  • 现在是最难的部分

  • 所以,正如你所理解的,在一个圆中(或与一个圆相交)意味着某个点离中心的距离必须小于或等于半径。 但是,我们也可以对矩形检查部分进行优化。与矩形相交可能意味着与构成矩形轮廓的至少一个线段相交。因此,在矩形与圆相交的情况下,您需要检查是否存在较小或相等的线段距离圆心的距离大于半径

  • 编辑:另外,代码在几乎不接触的测试中失败的原因可能是由于浮点错误。不要使用==(或者在这种情况下,您是否尝试过使用hipot函数?Java.lang.Math.hypot()方法我不明白这个函数在这种情况下是如何使用的。它是hypot。我将用手动平方替换Math.pow。但问题是,当矩形尺寸较小时,我通过了测试用例。我只会被发现超过了时间限制。所以我要解决的问题是以某种方式优化增量对“i”和“j”的值进行调整。当矩形的大小很大时,将它们增加1会导致太多的迭代,例如100x200。在这种情况下,迭代次数将变为20000次!但是如果我将增量值增加到某个较大的值,当矩形本身只有维度时,例如3x3,则会失败。我的解决方案是O(1)复杂度。我还用实际代码编辑了我的答案(并在网站上进行了测试,它应该可以在运行时1ms和37.7Mb内存使用情况下工作)@AjithKumar,但是,如果你非常有兴趣看看你是否可以简单地修改增量值,以获得几乎不超过时间限制的内容(我不建议这样做,正如我在这里所说的,你可以得到一个简单的O(1)时间和内存复杂性),没有办法对它进行大量修改。正如你所说,3x3矩形将失败(你可以使3x3矩形的增量值更小)。但你不能有大于2x2的间隙(对于半径为1的圆).也许只进行案例1中的检查,然后只验证边界中的像素就可以了。
    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;
        }
    }