在这篇文章中,我们讨论了如何使用二进制搜索找到一个数字的平方根。
目录
- 二进制搜索简介
- 二进制搜索的迭代和递归版本
- 使用二进制搜索寻找平方根
- 时间和空间的复杂性
前提条件
用二进制搜索寻找数字的平方根
在数组中搜索一个元素时,我们通常会遍历所有的元素,如果找到该元素,我们将返回该元素;否则,我们就说没有找到该元素。这种类型的搜索被称为线性搜索,其时间复杂度为O(n),我们在此使用二进制搜索来降低其时间复杂度。
二进制搜索
在进行二进制搜索时,我们应该确保数组是被排序的。二进制搜索遵循分而治之的方法,列表被分成两半,每次都将项目与中间的元素进行比较。如果中间元素小于要搜索的元素,那么我们就在列表的前半部分搜索该元素;否则,我们就在列表的后半部分搜索该元素。当中间元素等于搜索到的元素时,我们就说搜索成功并返回数值。
如果给定的数组没有被排序,那么首先对数组进行排序,然后应用二进制搜索方法。

我们一般有两种二进制搜索的方法。
迭代法
输入。
#include <bits/stdc++.h>
using namespace std;
//iterative method for binary search
int binarySearch(int arr[], int l, int r, int x)
{
while (l<= r) {
int m = l + (r - l) / 2;
//checing mid value
if (arr[m] == x)
return m;
//if x is greater than mid value we search only in right half and ignore left half
if (arr[m] < x)
l = m + 1;
//if x is lesser than mid value we search only in left half and ignore right half
else
r = m - 1;
}
// if element is not present we return -1
return -1;
}
int main(void)
{
//as we have discussed we take sorted array
int arr[] = { 12, 24,36,48,50 };
int x = 36;
int n = sizeof(arr) / sizeof(arr[0]);
int result = binarySearch(arr, 0, n - 1, x);
if(result == -1)
cout << "Element is not in the array";
else
cout << "Element is present at index " << result;
return 0;
}
输出。
Element is present at index 2
--------------------------------
Process exited after 0.0941 seconds with return value 0
Press any key to continue . . .
递归法(分而治之法)
输入
#include <bits/stdc++.h>
using namespace std;
// recursive method for binary search
int binarySearch(int arr[], int l, int r, int x)
{
if (r >= l) {
int mid = l + (r - l) / 2;
//cheching whether if element is present at middle
if (arr[mid] == x)
return mid;
//if x is lesser than mid value we search only in left half and ignore right half
if (arr[mid] > x)
return binarySearch(arr, l, mid - 1, x);
//if x is greater than mid value we search only in right half and ignore left half
return binarySearch(arr, mid + 1, r, x);
}
// if element is not found then we return -1
return -1;
}
int main(void)
{
int arr[] = { 12, 36, 48, 56,60 };
int x = 60;
int n = sizeof(arr) / sizeof(arr[0]);
int result = binarySearch(arr, 0, n - 1, x);
if(result == -1)
cout << "Element is not in the array";
else
cout << "Element is present at index " << result;
return 0;
}
输出
Element is present at index 4
--------------------------------
Process exited after 0.09934 seconds with return value 0
Press any key to continue . . .
使用二进制搜索寻找一个数字的平方根
在这里,如果一个给定的数字是完全平方,我们返回它的精确平方根值。如果它不是完全平方,我们返回它的下限值。
算法
第1步:我们知道我们只为正数寻找平方根值,并设置起始和结束值。
第二步:我们知道,所需的平方根值总是小于给定的值。因此,我们把终点值作为数字本身,并通过取起点和终点值的平均值来计算中间值。
注意:每次进入循环时,中间值都会发生变化。
第三步:接下来,我们计算中点的平方。如果它小于我们找到平方根的值,那么我们将只检查数组的右半部分,将低值更新为mid+1。如果该值大于我们找到的平方根的值,那么我们将在数组的左半部分进行搜索并更新较高的值,即end=mid-1。
第四步:现在,在找到积分部分后,我们通过每次递增0.1来找到小数部分,并找到所需精度的值。
第5步:最后,返回答案。
例子
| 输入 | 输出 |
|---|---|
| x=38,精度=4 | 6.1644 |
| x=75, 精度=5 | 8.66025 |
输入
#include <bits/stdc++.h>
using namespace std;
float squareRoot(int x, int precision)
{
int start = 1, end = x;
int mid;
float ans;
while (start <= end) {
//calculating mid value
mid = (start + end) / 2;
//if square of mid is equal to x then we return mid value
if (mid * mid == x) {
ans = mid;
break;
}
//if square of mid is less than x then we search in only right half of array
if (mid * mid < x) {
start = mid + 1;
ans = mid;
}
////if square of mid is greater than x then we search in only left half of array
else {
end = mid - 1;
}
}
float increment = 0.1;
//caluculating precision and this loop ends if ans square is greater than x
for (int i = 0; i < precision; i++) {
while (ans * ans <= x) {
ans += increment;
}
ans = ans - increment;
increment = increment / 10;
}
return ans;
}
int main()
{
cout << squareRoot(27, 3) << endl;
return 0;
}
输出
5.196
--------------------------------
Process exited after 0.08316 seconds with return value 0
Press any key to continue . . .
上述代码的解释
- 因此,我们正在寻找27的平方根值。 因此,终值等于27。现在我们计算中间值(27+1/2),它是14,14的平方小于27。这里我们将终值改为=13(14-1),所以平方小于数字。循环往复,直到一个数字的平方小于27,也就是25,然后ans=5。
- 现在我们通过使用while循环来计算精度,如果ANS值的平方小于x,则循环结束。
时间和空间复杂度
时间复杂度
- 我们知道,在进行二进制搜索时,我们将数组分成两半,每次只在数组的一半进行搜索,从而导致时间复杂度为对数。计算平方根值所需的时间为O(log(x)),计算平方根值的分数部分的时间为常数,因此总体时间复杂度为O(log(x)+精度),等于O(log(x))。
空间复杂度
- 空间复杂度为O(1),因为这里需要恒定的空间。
问题
- 你能改进这个二进制搜索吗?写出算法并计算其时间和空间复杂度。
- 寻找一个数字的平方根的各种方法是什么?说明哪种方法是更好的解决方案。