我一开始是看完了大话数据结构(好书!! 推荐),基本了解了二分查找法,但不能够熟悉他 ,所以就去了leetcode刷题,刷题路线是跟着代码随想录的(好网站),做的第一道题是 704. 二分查找https://leetcode-cn.com/problems/binary-search/
一开始没有使用到二分查找 ,直接暴力了,应该创建mid
class Solution {
public int search(int[] nums, int target) {
for(int i = 0;i
理解二分法的思想,正确做法:
class Solution {
public int search(int[] nums, int target) {
int low = 0, high = nums.length - 1;
while (low <= high) {
int mid = (high - low) / 2 + low;
int num = nums[mid];
if (num == target) {
return mid;
} else if (num > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
}
第二题是35. 搜索插入位置https://leetcode-cn.com/problems/search-insert-position/
他考察的还是二分法,但是 如果值不存在, 需要插入值保证有序
学到新知识点:要在二分查找的过程中,保持不变量,这也就是循环不变量,码中定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要) 。
当他不存在时,high 总会在他的前面,不管是low变大还是high变小
这是我的做法:
class Solution {
public int searchInsert(int[] nums, int target) {
int mid,low = 0,high = nums.length -1;
int n = 0;
while (low <= high){
mid = low +(high -low ) /2;
if(target nums[mid])
low = mid +1;
else
return mid;
n= mid;
}
return high +1;
}
}
而第三题是我的噩梦
34. 在排序数组中查找元素的第一个和最后一个位置https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
题目确实短,却要了我的命!!!!
但却让我掌握了二分法!!
让我注意到了二分法的边界问题。
这个博主讲的很好推荐!
【二分查找】详细图解_Charon_cc的博客-CSDN博客_二分查找
函数分别是寻找左边界和右边界:
我补充是:
二分法最重要的两个点:
第一种写法(左闭右闭)
• 循环条件要使用while(left <= right)
,因为当(left == right)
这种情况发生的时候,得到的结果是有意义的
• 循环条件修改为while (left < left)
•还未找到target的情况下算法就跳出了循环,返回 -1
右边界等于left
因为只有num >target时,范围会向左缩,但小于或等于时left会一直右移,移到刚刚大于target值的地方
同理左边界
class Solution {
public int[] searchRange(int[] nums, int target) {
int left = leftSearch(nums,target);
int right = rightSearch(nums,target);
if(left ==-2 ||right ==-2) return new int[]{-1,-1};
if(right -left >1) return new int[]{left +1,right -1};
return new int[]{-1,-1};
}
public int leftSearch(int[] nums,int target){
int mid,flag = -2,left = 0,right = nums.length -1;
while(left <= right){
mid = (right +left)/2;
if(nums[mid]target){
right = mid -1;
}else{
left = mid +1;
flag = left;
}
}
return flag;
}
}
第三第四题差不多
69.x 的平方根
一开始我想创建数组,然后再用二分查找,
其实用两个数的范围,就可以用二分查找,
• 0 <= x <= 231 - 1
还要注意变量的范围 ,需要扩大范围
class Solution {
public int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if ((long) mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
}
}
class Solution {
public boolean isPerfectSquare(int num) {
int low = 1 ,high = num,mid = 0,n = 0;
while(low<=high){
mid =(high +low) /2;
if(num <(long)mid*mid){
high = mid -1;
}else if( num >(long)mid*mid){
low = mid+1;
}else if(num == (long )mid *mid)
return true;
}
return false;
}
}
最后谢谢大家!!借用海明威激励自己!!!
一个人并不是生来要给打败的,你尽可以把他消灭掉,可就是打不败他。 --海明威