记这篇笔记的原因是我对二分法书写缺少一种标准和思维模式。
二分法理解起来虽然简单,但是在书写的时候有很多细节需要注意,比如二分的起始终止条件是什么(while(i!=j) while(i
实现一个简单的二分查找:对于升序数组,判断目标数target是否在数组中。
例如对于数组nums[1,4,5,7,8],8在数组中,而6不在数组中。
public boolean binarySearch(int[] nums,int target) {
int mid,i=0,j=nums.length;
while(i<=j) {
mid=(i+j)/2;
if(target==nums[mid]) return true;
else if(target>nums[mid]) i=mid+1;
else j=mid-1;
}
return false;
}
首先我们需要在数组中找到的是刚好等于目标数的数字,这里就提示了二分范围i和j缩进的形式:
当target>nums[mid]时:i=mid+1
当target
同时二分查找循环的条件是while(i<=j)
而不是while(i
i==j
的时候才会找到目标数。
如果不检查最后一遍i==j
的情况,二分查找就会失败。
有一个数组,要求当给一个目标数时,让目标数替换数组中刚好大于等于它的那个数。
例如对于nums[1, 3, 6]和target=2,由于3刚好是大于等于2的那个数,替换之后数组变为[1,2,6].
再例如对于数组nums[1,3,6,8,9,13,22],给定目标数为7后,可以替换掉数组中的8,数组变为[1,3,6,7,9,13,22]
public void binarySearch(int[] nums,int target) {
int mid,i=0,j=nums.length-1;
while(i!=j) {
mid=(i+j)/2;
if(target>nums[mid])
i=mid+1;
else
j=mid;
}
nums[i]=target;
}
首先我们需要在数组中替换的是大于等于目标数的数字,所以这里就提供了二分范围起点i和终点j的缩进形式为:
当target>nums[mid]时:我们要替换的数不可能是nums[mid],因为我们需要替换的数是大于等于target的数,而nums[mid]
当target
这个场景的应用在leetcode第300题上:
问题:https://leetcode.com/problems/longest-increasing-subsequence/submissions/
解法:https://segmentfault.com/a/1190000003819886