博主简介:大一计科生,努力学习Java中!热爱写博客~预备程序媛
所属专栏:LeetCode每日一题–进击大厂
✈往期博文回顾: 【JavaSE】保姆级教程|1万字+10张图学会类与对象–建议收藏
️♂️近期目标:成为千粉小博主。
“再牛的程序员也是从小白开始,既然开始了,就全身心投入去学习技术”
题型:数组、二分查找(变式)—寻找第1个大于等于目标值的元素
关键:二分查找的关键点就是—两边夹(高数上又叫作夹逼准则)。left和right确定答案所在区间,通过mid(把区间划分为[left,mid]&[mid+1,right]两个区间)来缩小区间范围,直到left==right,即获得答案。
思路:
1.确定答案可能取值区间[left,right]
2.left = 0;right = array.length;(因为此题中array.length也有可能为答案)
3.while(left
4.确定循环体中分支的两种情况:
5.left==right跳出循环体后:return right
为什么呢直接return left/right呢?我们来分析一下跳出循环后的两种情况
class Solution {
public int searchInsert(int[] nums, int target) {
int left=0,right=nums.length;//因为nums.length可能为答案
while (left<right){
int mid=left+(right-left)/2;//防止溢出(但其实left和right表示数组小标没什么必要)
if(target>nums[mid]){
left=mid+1;//下一次搜索区间为[mid+1,right]
}
else{
right=mid;//下一次搜素区间为[left,mid]
}
}
return right;
}
}
//下面是把区间划分为[left,mid-1]和[mid,right]的情况(错误代码)
class Solution {
public int searchInsert(int[] nums, int target) {
int left=0,right=nums.length;//因为nums.length可能为答案
while (left<right){
int mid=left+(right-left)/2;//防止溢出(但其实left和right表示数组小标没什么必要)
if(target<nums[mid]){
right=mid-1;//下一次搜索区间为[left,mid-1]
}
else{
left=mid;//下一次搜素区间为[mid,right]
}
}
return right;
}
}
死循环分析:
输入[1,3,5,6] 2出现超时。分析:
第一次循环:mid=2;区间被分为[0,1],[2…4],下一次搜索区间为[0,1],left:0,right:1
第二次循环:mid=0,left:0,right:1,下次循环区间还是[0,1]
第三次循环:mid=0,left:0,right:1,下次循环区间还是[0,1]
…死循环
【重点】二分法的关键是缩小区间
,死循环发生的原因是某次循环没有缩小区间导致二分失败。
【重点】此题right设置为array.length的原因是array.length也有可能是问题答案
【重点】将二分查找的判断条件写成while(left
【重点】循环不变量:在[left,right]搜索答案
write in the end: