📜  不使用sqrt()函数的地板平方根:递归

📅  最后修改于: 2021-04-24 17:00:33             🧑  作者: Mango

给定数字N ,任务是在不使用内置平方根函数的情况下找到数字N的底平方根。底数平方根是小于或等于其平方根的最大整数。

例子:

天真的方法:
在找到数字的底平方根的基本方法中,找到从1到N的数字平方,直到某个数字K的平方变得大于N为止。因此, (K – 1)的值将是N的平方根。

以下是使用Naive方法解决此问题的算法:

  • 从K中的数字1到N循环循环。
  • 对于任何K,如果其平方变得大于N,则K-1是N的底平方根。

时间复杂度: O(√N)

高效方法:
从天真的方法来看,很明显N的底平方根将在[1,N]范围内。因此,代替检查该范围内的每个数字,我们可以有效地搜索该范围内的所需数字。因此,该思想是使用二进制搜索以便有效地找到log N中数字N的平方根。

下面是使用二进制搜索解决上述问题的递归算法:

  1. 实施二进制搜索,范围为0到N。
  2. 使用公式找到范围的中间值:
    mid = (start + end) / 2
    
  3. 基本情况:将执行递归调用,直到mid的平方小于或等于N并且(mid + 1)的平方大于等于N为止。
    (mid2 ≤ N) and ((mid + 1)2 > N)
    
  4. 如果不满足基本要求,则范围将相应更改。
    • 如果mid的平方小于N,则范围将更新为[mid + 1,end]
      if(mid2 ≤ N)
          updated range = [mid + 1, end]
      
    • 如果mid的平方大于N,则范围将更新为[low,mid + 1]
      if(mid2 > N)
          updated range = [low, mid - 1]
      

下面是上述方法的实现:

C++
// C++ implementation to find the
// square root of the number N
// without using sqrt() function
  
#include 
using namespace std;
  
// Function to find the square
// root of the number N using BS
int sqrtSearch(int low, int high, int N)
{
  
    // If the range is still valid
    if (low <= high) {
  
        // Find the mid-value of the range
        int mid = (low + high) / 2;
  
        // Base Case
        if ((mid * mid <= N)
            && ((mid + 1) * (mid + 1) > N)) {
            return mid;
        }
  
        // Condition to check if the
        // left search space is useless
        else if (mid * mid < N) {
            return sqrtSearch(mid + 1, high, N);
        }
        else {
            return sqrtSearch(low, mid - 1, N);
        }
    }
    return low;
}
  
// Driver Code
int main()
{
    int N = 25;
    cout << sqrtSearch(0, N, N)
         << endl;
    return 0;
}


Java
// Java implementation to find the
// square root of the number N
// without using sqrt() function
class GFG {
      
    // Function to find the square
    // root of the number N using BS
    static int sqrtSearch(int low, int high, int N)
    {
      
        // If the range is still valid
        if (low <= high) {
      
            // Find the mid-value of the range
            int mid = (int)(low + high) / 2;
      
            // Base Case
            if ((mid * mid <= N)
                && ((mid + 1) * (mid + 1) > N)) {
                return mid;
            }
      
            // Condition to check if the
            // left search space is useless
            else if (mid * mid < N) {
                return sqrtSearch(mid + 1, high, N);
            }
            else {
                return sqrtSearch(low, mid - 1, N);
            }
        }
        return low;
    }
      
    // Driver Code
    public static void main (String[] args)
    {
        int N = 25;
        System.out.println(sqrtSearch(0, N, N));
    }
}
  
// This code is contributed by Yash_R


Python3
# Python3 implementation to find the 
# square root of the number N 
# without using sqrt() function 
  
# Function to find the square 
# root of the number N using BS 
def sqrtSearch(low, high, N) : 
  
    # If the range is still valid 
    if (low <= high) :
  
        # Find the mid-value of the range 
        mid = (low + high) // 2; 
  
        # Base Case 
        if ((mid * mid <= N) and ((mid + 1) * (mid + 1) > N)) :
            return mid; 
  
        # Condition to check if the 
        # left search space is useless 
        elif (mid * mid < N) : 
            return sqrtSearch(mid + 1, high, N); 
      
        else :
            return sqrtSearch(low, mid - 1, N); 
  
    return low; 
  
# Driver Code 
if __name__ == "__main__" : 
  
    N = 25; 
    print(sqrtSearch(0, N, N)) 
  
# This code is contributed by Yash_R


C#
// C# implementation to find the
// square root of the number N
// without using sqrt() function
using System;
  
class GFG {
       
    // Function to find the square
    // root of the number N using BS
    static int sqrtSearch(int low, int high, int N)
    {
       
        // If the range is still valid
        if (low <= high) {
       
            // Find the mid-value of the range
            int mid = (int)(low + high) / 2;
       
            // Base Case
            if ((mid * mid <= N)
                && ((mid + 1) * (mid + 1) > N)) {
                return mid;
            }
       
            // Condition to check if the
            // left search space is useless
            else if (mid * mid < N) {
                return sqrtSearch(mid + 1, high, N);
            }
            else {
                return sqrtSearch(low, mid - 1, N);
            }
        }
        return low;
    }
       
    // Driver Code
    public static void Main(String[] args)
    {
        int N = 25;
        Console.WriteLine(sqrtSearch(0, N, N));
    }
}
  
// This code is contributed by PrinciRaj1992


输出:
5

性能分析:

  • 时间复杂度:与上述方法一样,在最坏的情况下,在0到N的搜索空间上使用二进制搜索会占用O(log N)时间,因此时间复杂度将为O(log N)
  • 空间复杂度:与上述方法一样,考虑在递归调用中使用的堆栈空间,在最坏的情况下它可能占用O(logN)空间,因此空间复杂度将为O(log N)