思路1: 伪二分查找。若中间元素正好是target时,分四种小情况:1)左右边界也等于target时,当前这段就是要找的范围,可直接返回;2)只有左边界等于target,则右边界往左靠近一步;3)只有右边界等于target,则左边界往右靠近一步;4)左右边界均不等于target,则左右均往里逼近一步。容易看出在中间元素恰好是target时,算法退化为O(N)的。
思路2: 二分法依次查找target第一次出现和最后一次出现的位置。
[ref]
二分查找(Binary Search) 常见问题解决方法总结
http://blog.csdn.net/daniel_ustc/article/details/17307937
http://bangbingsyb.blogspot.com/2014/11/leetcode-search-for-range.html
public class Solution { // Method 2: O(logN) public int[] searchRange(int[] nums, int target) { int[] result = {-1, -1}; if (nums == null || nums.length == 0) return result; result[0] = binarySearchFirst(nums, target); if (result[0] != -1) { result[1] = binarySearchLast(nums, target); } return result; } // 查找target在nums[]中第一次出现的下标,若找不到返回-1 public int binarySearchFirst(int[] nums, int target) { if (nums == null || nums.length == 0) return -1; int left = 0, right = nums.length - 1; int mid = 0; while (left < right) { // 此处不能有等号,否则可能在right=mid处死循环,考虑case:[1], 1 mid = left + ((right - left) >> 1); if (target > nums[mid]) left = mid + 1; else right = mid; } if (nums[left] == target) return left; return -1; } // 查找target在nums[]中最后一次出现的下标,若找不到返回-1 public int binarySearchLast(int[] nums, int target) { if (nums == null || nums.length == 0) return -1; int left = 0, right = nums.length - 1; int mid = 0; while (left + 1 < right) { // 循环只处理元素个数大于两个的情况,两个以下元素时可能在left=mid处死循环(两个元素时left==mid),考虑case:[1,1],1 mid = left + ((right - left) >> 1); if (target < nums[mid]) right = mid - 1; else left = mid; } if (nums[right] == target) return right; else if(nums[left] == target) return left; return -1; } // Method 1 public int[] searchRange1(int[] nums, int target) { int[] result = {-1, -1}; if (nums == null || nums.length == 0) return result; int left = 0, right = nums.length - 1; int mid = 0; while (left <= right) { mid = left + (right - left) / 2; if (nums[mid] > target) right = mid - 1; else if (nums[mid] < target) left = mid + 1; else { if (nums[left] == nums[mid] && nums[mid] == nums[right]) { result[0] = left; result[1] = right; return result; } else if (nums[left] == nums[mid]) { right--; } else if (nums[right] == nums[mid]) { left++; } else { left++; right--; } } } return result; } }