学习算法的Day1 二分法处理平方根
平方根有递归、二分法、牛顿迭代法三种方法解决,本文采用二分法(因为day1练习二分法)
题目链接如下:
https://leetcode-cn.com/problems/valid-perfect-square/
代码如下:
class Solution {
public boolean isPerfectSquare(int num) {
long left = 0, right = num / 2;
long mid = 0;
if(num < 2) return true;
while(left <= right){
mid = left + (right - left) / 2;
long guess = mid * mid;
if (guess == num) return true;
if (guess < num) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}
}
这里需要注意以下几点:
- 变量需要设置成long(64bit)而不是int(32bit),因为在使用二分法时,mid * mid可能会越界,如果要使用int的话,判定条件就要将(mid * mid == num)替换为(mid == num / mid && num % mid == 0),我没尝试,朋友们可以试试。
- 在二分的时候,left = mid + 1 而不是 left = mid,因为如果不这么做可能会进入无限循环,比如left = 3,right = 4,mid = 3,而num = 14,循环内一直判定为left = mid。而right = mid or right = mid - 1亲测在这题是不影响结果的,原因是while循环判定终止条件是left <= right 而不是left >= right,如果是后者,right = mid - 1 避免进入无限循环。
- left <= right和left < right作为循环终止条件在本题内没有差别,但是在一般二分法中差别很大,详情请见后文。
二分法一般用于寻找有序数组中的元素,有些题目会出现相同元素,需要查找最左边界值或者最右边界值。
二分法需要注意的几个点:
- while循环中的left < right 是否加上 "="
- right = nums.length or right = nums.length - 1
- left = mid + 1 or left = mid
- right = mid or right = mid - 1
这些细节都要视情况而定,而且相互关联,可以阅读下面文章仔细理解。(ps:写得超棒!)