Leetcode: Find First and Last Position of Element in Sorted Array

Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

Analysis: 这道题是二分查找Search Insert Position的变体,思路并不复杂,就是先用二分查找找到其中一个target,然后再往左右找到target的边缘。找边缘的方法跟二分查找仍然是一样的,只是相等的情况依然要往左找(找左边缘)或往右找(找右边缘)。这样下来总共进行了三次二分查找,所以算法的时间复杂度仍是O(logn),空间复杂度是O(1)。

Notice: 对停止的边界条件极不熟悉,需要总结,参见Binary Search的Summary

本题的精髓和难点在于寻找左右边沿,方法是Binary Search的变体,只不过这次是要左右相遇。以找左边缘为例,while循环里要么A[m] < target, l 跳到m+1, 要么A[m]==target, r 跳到m-1, 直到l > r为止,这时候l所在的位置就是要求的左边缘。而如果是找右边缘,l > r之后,r所在位置就是要求的右边缘。l和r所停的位置正好是目标数的后面和前面。

找左边沿可以认为是在找一个比target略小的目标数(因为等于target的时候移动的是右边缘),这个目标数在A中不存在,所以当循环结束时候,l, r分别处在目标数的后面和前面。如果我们找的是左边缘,那么这个左边缘应该是在目标数右边,所以就是l所处的位置

整体如果想用iterative的方法来写:

两次binary search, 一次找左边缘,一次找右边缘, be carefule of line 12, r有可能<0

 1 public class Solution {
 2     public int[] searchRange(int[] nums, int target) {
 3         int[] res = new int[]{-1, -1};
 4         if (nums==null || nums.length==0) return res;
 5         int l=0, r=nums.length-1;
 6         int m = l + (r-l)/2;
 7         while (l <= r) { // find right edge
 8             m = l + (r-l)/2;
 9             if (nums[m] <= target) l = m + 1;
10             else r = m - 1;
11         }
12         if (r<0 || nums[r] != target) return res;
13         else res[1] = r;
14         
15         l = 0;
16         //no need to set r = nums.length - 1, because r is already at right place
17         while (l <= r) {
18             m = l + (r-l)/2;
19             if (nums[m] < target) l = m + 1;
20             else r = m - 1;
21         }
22         res[0] = l;
23         return res;
24     }
25 }
原文地址:https://www.cnblogs.com/EdwardLiu/p/3811193.html