Javascript 在O(lgn)时间内求解完全平方时如何避免角点情况?

Javascript 在O(lgn)时间内求解完全平方时如何避免角点情况?,javascript,algorithm,big-o,binary-search,Javascript,Algorithm,Big O,Binary Search,下面的代码将查找给定的数字是否是Olg N中的完美正方形。如果num==1{return true;}在下面的解决方案中给出,我如何避免硬编码角情况?有什么想法吗 var isPerfectSquare = function(num) { let floor = 0, ceiling = num, mid; // Corner case if (num === 1) { return true; } while (floor != ce

下面的代码将查找给定的数字是否是Olg N中的完美正方形。如果num==1{return true;}在下面的解决方案中给出,我如何避免硬编码角情况?有什么想法吗

var isPerfectSquare = function(num) {
    let floor = 0, ceiling = num, mid;

    // Corner case
    if (num === 1) {
        return true;
    }

    while (floor != ceiling) {
        mid = floor + (ceiling - floor) / 2 | 0;
        let mul = mid * mid;

        if (mul === num) {
            return true;
        }

        if (mul > num) {
            ceiling = mid;
        }
        else if (mul < num) {
            floor = mid+1;
        }   
    }
    return false;
};

通过将while循环中的条件更改为,可以避免num==1的特定边界情况

而地板<天花板-1

这就足够了,因为如果地板和天花板之间的差值为1,那么您将进入一个无限循环,因为地板+天花板地板/2在四舍五入时始终等于地板

我刚刚尝试了下面的Java实现,看起来不错

public static void isPerfectSquare(int num){
     int low = 0;
     int high = num;
     int mid;
     while(low<high-1){
         mid = low + (high-low)/2;
         System.out.println("high-- " + high + " low-- " + low + " mid---" + mid);
         int square = mid*mid;
         if(square==num){
             System.out.println("Found ->" + mid);           
             break;
         }
         else if(square<num){
             low = mid;          
         }
         else if(square>num){
             high = mid;             
         }       
     }
    }

通过保持smart不变量,我们可以更改代码,使其最终只需要进行一次相等性检查。应该适用于所有输入

var isPerfectSquare = function(num) {
    let floor = 0, ceiling = num+1, mid;
    // We will keep the invariants: floor*floor <= num,
    //   ceiling * ceiling > num

    while (ceiling - floor > 1) {
        mid = floor + (ceiling - floor) / 2 | 0;
        let mul = mid * mid;

        // Move one of floor/ceiling to mid
        // Retains the invariant!
        if (mul > num) {
            ceiling = mid;
        } else {
            floor = mid;
        }   
    }
    return floor * floor === num;
};

我可能弄错了语言语法,但这个想法应该行得通。

可能重复的@P0W至少在标记为重复之前阅读问题的第一行。我不需要找到更快的解决方案。我的问题是关于避免一个极端情况。@P0W,建议的重复被标记,即使接受的答案是C++@baltusaj,是的,我知道不是,即使不阅读问题正文,也不应该这样解释。标签上已经说不是了。一个小小的改变就可以了。。请检查下面的溶液是否干净。谢谢但是一些数学学家认为零不是一个完美的正方形。要避免为零,只需从floor=1开始