二分查找
一、思路
使用二分查找的前提是数组是有序的,思路是把整个数组根据中点一分为二,如果target小于中点,则将搜索目标缩小为左半部分再继续搜索,否则搜索目标缩小为右半部分,直到找到中点为target返回。
二、解题模板
int binarySearch(int[] nums, int target) { int left = 0, right = nums.length-1; while(left<=right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid+1; } else if (nums[mid] > target) { right = mid-1; } } return -1; }
注意:(1)left值和right值都是nums的可访问下标,因此搜索区间为左闭右闭。所以,当left==right时,搜索区间还有一个数,依旧可以进入循环。另外,当搜 索区间缩小时,也应该防止再将mid纳入搜索区间(即left=mid+1或right=mid-1)。
(2)计算 mid
时需要防止溢出,代码中 left + (right - left) / 2
就和 (left + right) / 2
的结果相同,但是有效防止了 left
和 right
太大,直接相加导致溢出的情况。
三、特殊情况
找左边界:当找到num[mid]==target时不要急着返回,而是缩小右边界;最后返回left(取值为[0,num.length])所以要判断是否越界(left<num.length)
找右边界:当找到num[mid]==target时不要急着返回,而是缩小左边界;最后返回right(left-1 == right),right取值为[-1,num.length-1],所以要判断是否越界(right<0)
参考:labuladong算法小抄