二分查找----3.在排序数组中查找元素的第一个和最后一个位置
题目链接
/**
在一个近似递增的数组中查找指定元素,该元素可能有多个找出其出现的区间
单次普通二分只能查到一个元素且无法确定边界;对二分改进即可
左边界:当查到目标元素时,记录下标并将right迭代为mid-1,继续向左二分直到搜寻结束,得到左边界
右边界:当查到目标元素时,记录下标并将left迭代为mid+1,继续向右二分直到搜寻结束,得到右边界
即进行两次改进二分,查找左边界与右边界
优化:
查找左边界与右边界大量代码相同,仅left与right指针迭代逻辑不同
添加变量boolean isLeft,控制查找方向,一个方法即可完成左、右边界的查找
*/
class Solution {/**在一个近似递增的数组中查找指定元素,该元素可能有多个找出其出现的区间单次普通二分只能查到一个元素且无法确定边界;对二分改进即可左边界:当查到目标元素时,记录下标并将right迭代为mid-1,继续向左二分直到搜寻结束,得到左边界右边界:当查到目标元素时,记录下标并将left迭代为mid+1,继续向右二分直到搜寻结束,得到右边界即进行两次改进二分,查找左边界与右边界优化:查找左边界与右边界大量代码相同,仅left与right指针迭代逻辑不同添加变量boolean isLeft,控制查找方向,一个方法即可完成左、右边界的查找*/public int[] searchRange(int[] nums, int target) {//搜寻左边界int left = findBound(nums, target, true);if(left == -1) { //若为-1代表不存在该元素,无需继续搜寻return new int[]{-1,-1};}//搜寻右边界int right = findBound(nums, target, false);return new int[]{left, right};}private int findBound(int[] nums, int target, boolean isLeft) {//双指针,置于有效部分两端int left = 0, right = nums.length - 1;//不断迭代,记录已探明的边界int index = -1;while(left <= right) {//均分数组,缩小查找范围int mid = left + right >>> 1;//目标值在右半区,淘汰左半区if(nums[mid] < target) {left = mid + 1;}//目标值在左半区,淘汰右半区else if(nums[mid] > target) {right = mid - 1;}//查找到元素,迭代index,并依据findLeft确定查找方向else {index = mid;if(isLeft) { //向左继续二分,迭代rightright = mid - 1;} else { //向右二分,迭代leftleft = mid + 1;}}}return index;}
}