package binary_search; /** * 题目: 34. 在排序数组中查找元素的第一个和最后一个位置 (searchRange) * 描述:给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 * 如果数组中不存在目标值 target,返回 [-1, -1]。 * 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 * 示例 1: 输入:nums = [5,7,7,8,8,10], target = 8 输出:[3,4] * 链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/ */ public class SearchRange { //极端情况下不是O(log n) public int[] searchRange(int[] nums, int target) { int left=0,right=nums.length-1; int tpleft=-1,tpright=-1; while (left<=right){ int mid=(left+right)/2; if(target==nums[mid]){ tpleft=mid-1; tpright=mid+1; while (tpleft>=left) { if (target == nums[tpleft]) tpleft--; else break; } tpleft++; while (tpright<=right) { if (target == nums[tpright]) tpright++; else break; } tpright--; break; } else if(target>nums[mid]) left=mid+1; else right=mid-1; } return new int[]{tpleft,tpright}; } private int findLeft(int[] nums, int target) { int left = 0, right = nums.length - 1; int index = -1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] >= target) { right = mid - 1; } else { left = mid + 1; } if (nums[mid] == target) { index = mid; } } return index; } // 找到目标值的最后一次出现位置 private int findRight(int[] nums, int target) { int left = 0, right = nums.length - 1; int index = -1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] <= target) { left = mid + 1; } else { right = mid - 1; } if (nums[mid] == target) { index = mid; } } return index; } public int[] searchRange1(int[] nums, int target) { int leftIndex = findLeft(nums, target); int rightIndex = findRight(nums, target); return new int[]{leftIndex, rightIndex}; } }