目录
浮点数有误差,迭代误差范围在1e-6或在1e-7内,用0.5而非1/2,因为1和2是Int类型,而0.5有小数
算平方根的时候,mid*mid如果是Int*int类型很容易超出范围,容易overflow,所以需要加longlong
区间是否闭区间还是开区间,小心while条件以及left和right取值
1/2最好用0.5来代替,如果是1/2容易没有小数,只是int类型。
一、X的平方根
二分法方法
x = (int)(input("请输入目标值"))
def BinarySearchSqrtX(x):
left,right=0,x
while left<=right:
mid=left + (right-left)//2
if mid*mid<=x:#Python是没有long类型,所以不需要,如果是其他语言,Int是会overflow
ans = mid
left=mid+1
else:
right=mid-1
return ans
def BinarySearchSqrtX(x):#时间复杂度为o(logn)
left,right=0,x
while left<right:
mid=left + (right-left)//2+1
if mid*mid<=x:
left=mid
else:
right=mid-1
return left
print(BinarySearchSqrtX(x))
袖珍计算器
def BinarySearchSqrtX_1(x):#时间复杂度为o(1),袖珍计算器
if x==0:
return 0
ans = (int)(math.exp(0.5*math.log(x)))#e^1/2log(x)
#主要是因为浮点数有误差,例如2147395600,正确结果应为46340,而不是46339
if (ans+1)**2<=x:
return ans+1
else:
return ans
print(BinarySearchSqrtX_1(x))
牛顿迭代法
#牛顿迭代法
def BinarySearchSqrtX_2(x):#时间复杂度为o(logn)
if x==0:
return 0
C,x0 = float(x),float(x)
while True:
xi = 0.5*(x0+C/x0)
if abs(xi-x0)<1e-7:#采用1e-7或1e-6误差
break;
x0 = xi
return int(x0)
print(BinarySearchSqrtX_2(x))
def BinarySearchSqrtX_4(x):#时间复杂度为o(logn)
if x==0:
return 0
t = x
while (t*t-x>=1):#固定一个x,看t是否在x的左边
t = 0.5*(t+x/t)
return int(t)
print(BinarySearchSqrtX_4(x))
二、搜索插入位置
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left,right = 0,len(nums)-1
while left<=right:
mid = left + (right-left)//2
if nums[mid]<target:
left = mid + 1
elif nums[mid]>target:
right = mid -1
else:
return mid
return left
三、有效的完全平方数
二分查找
bool isPerfectSquare(int num) {
int left=0,right=num-1,middle;
while(left<=right)
{
middle = left+(right-left)/2;
if(middle*middle<num)
left = middle+1;
else if(middle*middle>num)
right = middle-1;
else
return true;
}
return false;
}
使用内置的库函数
def BinarySearchSqrtXBool(x):
return float.is_integer(pow(x,0.5))
print(BinarySearchSqrtXBool(x))
public class Solution {
public bool IsPerfectSquare(int num) {
int x = (int)Math.Sqrt(num);
return x*x==num;
}
}
暴力方法
def BinarySearchSqrtXBool_1(x):
sum=temp=1
while temp<=x:
if temp==x:
return True
sum+=1
temp = sum*sum
return False
print(BinarySearchSqrtXBool_1(x))
def BinarySearchSqrtXBool_3(x):#暴力的变种
i = 1
while x>0:#完全平方数是从1开始的连续奇数之和
x-=i
i+=2
return x == 0
print(BinarySearchSqrtXBool_3(x))
牛顿迭代法
def BinarySearchSqrtXBool_2(x):
x0 = float(x)
while True:
xi = 0.5*(x0+x/x0)
if abs(xi-x0)<1e-7:
break
x0 = xi
x0 = int(x0)
return x0*x0==x
print(BinarySearchSqrtXBool_2(x))
总结
注意点:
浮点数有误差,迭代误差范围在1e-6或在1e-7内,用0.5而非1/2,因为1和2是Int类型,而0.5有小数
算平方根的时候,mid*mid如果是Int*int类型很容易超出范围,容易overflow,所以需要加longlong
二分法的需要注意在区间是否闭区间还是开区间,这样确定while循环条件的left<right还是left<=right,以及mid和right的取值,如果不清楚,可以举简单的例子,比如[3,3]那么需要取到则,left<=right,如果右开区间,那么right=mid
以及在python语言取整的话要用//而不是/。
平方根以及完全平方数可以使用牛顿迭代法来求解,y=x^2-sum,斜率为f'(x)=2x,xi+1=(xi+sum/xi)/2
归纳一下几点:
-
注意//还是/(python)
-
注意是longlong,小心overflow
-
浮点数有误差,范围一般为1e-6还是1e-7
-
区间是否闭区间还是开区间,小心while条件以及left和right取值
-
1/2最好用0.5来代替,如果是1/2容易没有小数,只是int类型。
-
平方根以及完全平方数可以使用到牛顿迭代法。