1.704二分查找
二分查找的 框架:
int binarySearch(int[] nums, int target)
{
int left = 0, right = ...;
while(...)
{
int mid = left + (right - left) / 2;
if (nums[mid] == target) { ... }
else if (nums[mid] < target) { left = ... }
else if (nums[mid] > target) { right = ... }
}
return ...;
}
1.主体while(...)循环的条件判断不知道该写什么:
最初的想法是写判断nums[mid]==target 但又很疑惑 因为如果未找到目标的话就是死循环了
实在不知该怎么写--去看了答案之后应该与left<right有关
但我以为left应该恒小于right
仔细想了一下 假设target在靠数组左边区域,那么前面几次nums[mid]都是大于target,
(这里不妨假设nums: 1 2 4 target为3 左闭右闭区间)判断条件是:left<=right
mid=2--->num[2]=4>3--->right=mid-1=1--->(下一轮循环)mid=0--->num[0]=1<3--->left=mid+1=1--->条件判断left>right 退出循环
即判断条件中如果target不在数组中,循环过程中left/right就会越过target导致left right左右颠倒 退出循环
2.mid为什么是left+(right-left)/2而不是(left+right)/2
调试的时候int mid=(left+right)/2 运行时长比left+(right-left)/2时间慢
应当考虑当right足够大时,left+right可能结果太大 导致溢出
3.应用二分法的条件
适用于无重复数组
区间为左开右闭
#include <stdio.h>
//*nums数组指针,numsSize数组大小,target目标数字
int search(int* nums, int numsSize, int target){
int left=0;
int right=numsSize-1;
//区间为左闭右开
while (left<right) {
int mid=left + (right-left)/2;
if(nums[mid]==target)return mid;
else if (nums[mid]>target)
{
right=mid;//右为开区间 如果是mid-1 前一个元素可能为target不被取到 所以右边界改为mid
}
else if (nums[mid]<target)left=mid+1;
}
return -1;
}
左闭右闭
int search01(int* nums, int numsSize, int target){
//左闭右闭
int left=0;
int right=numsSize-1;
while (left<=right)//左闭右闭区间 [a,b]定义可以a=b
{
int mid=left + (right-left)/2;
if(nums[mid]==target)return mid;
else if (nums[mid]>target)
{
right=mid-1;
}
else if (nums[mid]<target)left=mid+1;
}
return -1;
}