题目一:二分搜索
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
链接:https://leetcode-cn.com/problems/binary-search/
思路:
这个是最常规的二分法的问题,不断地缩小搜索范围来找到最终的值。以下代码可以作为此类题目的模板。
代码:
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = (left + right) >>> 1;
if(target == nums[mid]) {
return mid;
} else if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
}
}
题目二:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
链接:https://leetcode-cn.com/problems/search-insert-position/
思路:
思路基本就是二分查找的思路,差别就在于如果没有找到目标值,返回的是插入的位置。
代码:
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = (left + right) >>> 1;
if(target == nums[mid]) {
return mid;
} else if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
题目三:X的平方根
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
链接:https://leetcode-cn.com/problems/sqrtx/
思路:
X的平方根一定在0~X之间,我们可以采用二分法来解决这个问题。注意这道题要使用long类型,因为int型的数据平方之后可能超过int型数据的表示范围。具体到代码里,这道题目与前两道题目的不同点在于判定条件。于此类似的问题不同点可以看作是做判断的那一步骤不同,思想大同小异。
还有几点要注意:①求中间的数:最好使用mid = (left + right) >>> 1(左中位数)或者mid = (left + right + 1) >>> 1(右中位数),区分左右中位数的原因是在某些情况下,选择默认的左中位数,会进入死循环,因此这里要具体情况具体分析。②while语句的判定条件:最好使用left < right,因为这样可以在while循环结束后,不用去考虑left和right的情况,基本是left==right的情况,才会跳出循环。
代码:
class Solution {
public int mySqrt(int x) {
if(x == 0) {
return 0;
}
long left = 1;
long right = x;
while(left < right) {
//进入右中位数
long mid = (left + right + 1) >>> 1;
long square = mid * mid;
if(square > x) {
right = mid - 1;
} else {
left = mid;
}
}
return (int)left;
}
}
题目四:有效的完全平方数
给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。
说明:不要使用任何内置的库函数,如 sqrt。
链接:https://leetcode-cn.com/problems/valid-perfect-square/
思路:
思路与上一题基本一致。要注意一点,跳出while循环之后,要对left(right)的数据进行处理,不然会漏掉那个数据。
代码:
class Solution {
public boolean isPerfectSquare(int num) {
if(num == 0 || num == 1) {
return true;
}
long left = 1;
long right = num / 2;
while(left < right) {
long mid = (left + right) >>> 1;
long square = mid * mid;
if(square == num) {
return true;
} else if(square > num) {
right = mid;
} else {
left = mid + 1;
}
}
if(left * left == num) {
return true;
}
return false;
}
}
题目五:Pow(x, n)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
链接:https://leetcode-cn.com/problems/powx-n/
思路:
采用二分递归的思想,,不断的计算
,使用递归求出结果。
代码:
class Solution {
public double myPow(double x, int n) {
if(n == 1) {
return x;
}
if(n == -1) {
return 1 / x;
}
if(n == 0) {
return 1;
}
double temp = myPow(x, n / 2);
double rest = myPow(x, n % 2);
double ans = temp * temp * rest;
return ans;
}
}
参考资料:
https://www.liwei.party/2019/06/19/leetcode-solution-new/search-insert-position/
后续更新细节。
本文精选了五道LeetCode上的二分法经典题目,包括二分搜索、搜索插入位置、X的平方根、有效的完全平方数及Pow(x,n),详细解析了每道题目的解题思路与代码实现,为读者提供了深入理解二分法技巧的机会。
2365

被折叠的 条评论
为什么被折叠?



