1414如果数组中不存在目标值 target,返回 [ -1, -1] 。
1515
1616进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
17-
17+
1818
1919示例 1:
2020* 输入:nums = [ 5,7,7,8,8,10] , target = 8
@@ -173,8 +173,105 @@ private:
173173## Java
174174
175175```java
176+ class Solution {
177+ int[] searchRange(int[] nums, int target) {
178+ int leftBorder = getLeftBorder(nums, target);
179+ int rightBorder = getRightBorder(nums, target);
180+ // 情况一
181+ if (leftBorder == -2 || rightBorder == -2) return new int[]{-1, -1};
182+ // 情况三
183+ if (rightBorder - leftBorder > 1) return new int[]{leftBorder + 1, rightBorder - 1};
184+ // 情况二
185+ return new int[]{-1, -1};
186+ }
187+
188+ int getRightBorder(int[] nums, int target) {
189+ int left = 0;
190+ int right = nums.length - 1;
191+ int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
192+ while (left <= right) {
193+ int middle = left + ((right - left) / 2);
194+ if (nums[middle] > target) {
195+ right = middle - 1;
196+ } else { // 寻找右边界,nums[middle] == target的时候更新left
197+ left = middle + 1;
198+ rightBorder = left;
199+ }
200+ }
201+ return rightBorder;
202+ }
203+
204+ int getLeftBorder(int[] nums, int target) {
205+ int left = 0;
206+ int right = nums.length - 1;
207+ int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
208+ while (left <= right) {
209+ int middle = left + ((right - left) / 2);
210+ if (nums[middle] >= target) { // 寻找左边界,nums[middle] == target的时候更新right
211+ right = middle - 1;
212+ leftBorder = right;
213+ } else {
214+ left = middle + 1;
215+ }
216+ }
217+ return leftBorder;
218+ }
219+ }
176220```
177221
222+ ``` java
223+ // 解法2
224+ // 1、首先,在 nums 数组中二分查找 target;
225+ // 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
226+ // 3、如果二分查找失败,则 binarySearch 返回 nums 中 为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
227+
228+ class Solution {
229+ public int [] searchRange (int [] nums , int target ) {
230+ int index = binarySearch(nums, target); // 二分查找
231+
232+ if (index == - 1 ) { // nums 中不存在 target,直接返回 {-1, -1}
233+ return new int [] {- 1 , - 1 }; // 匿名数组
234+ }
235+ // nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
236+ int left = index;
237+ int right = index;
238+ // 向左滑动,找左边界
239+ while (left - 1 >= 0 && nums[left - 1 ] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
240+ left-- ;
241+ }
242+ // 向左滑动,找右边界
243+ while (right + 1 < nums. length && nums[right + 1 ] == nums[index]) { // 防止数组越界。
244+ right++ ;
245+ }
246+ return new int [] {left, right};
247+ }
248+
249+ /**
250+ * 二分查找
251+ * @param nums
252+ * @param target
253+ */
254+ public int binarySearch (int [] nums , int target ) {
255+ int left = 0 ;
256+ int right = nums. length - 1 ; // 不变量:左闭右闭区间
257+
258+ while (left <= right) { // 不变量:左闭右闭区间
259+ int mid = left + (right - left) / 2 ;
260+ if (nums[mid] == target) {
261+ return mid;
262+ } else if (nums[mid] < target) {
263+ left = mid + 1 ;
264+ } else {
265+ right = mid - 1 ; // 不变量:左闭右闭区间
266+ }
267+ }
268+ return - 1 ; // 不存在
269+ }
270+ }
271+ ```
272+
273+
274+
178275## Python
179276
180277``` python
@@ -196,4 +293,3 @@ private:
196293* 知识星球:[ 代码随想录] ( https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ )
197294<div align="center"><img src=../pics/公众号.png width=450 alt=> </img ></div >
198295
199-
0 commit comments