思路:
题意很明显了,要使用二分搜索在O(lgn)时间内找到第一次出现和最后一次出现的目标下标,如果没有出现,则返回-1。
一直以来都只会写最基本的二分查找(找到就停那种),要么就是为了省事直接用Arrays.binarySearch(arr, target);
这次自己写了下,感觉也不是很难。
在最基本的版本上增加两个东西:
1. 不是找到就停,而是继续压缩查找空间。first就压缩上界;last就压缩下界。
2. 由于不知道何时停止,需要一个变量ind来不断更新target对应的下标。
1 class Solution { 2 public int[] searchRange(int[] nums, int target) { 3 // return new int[]{firstBinarySearch(nums, target), 4 // lastBinarySearch(nums, target)}; 5 return new int[]{specialBinarySearch(nums, target, true), 6 specialBinarySearch(nums, target, false)}; 7 } 8 9 public int firstBinarySearch(int[] nums, int target) { 10 int low = 0, high = nums.length - 1; 11 int ind = -1; 12 while (low <= high) { 13 int mid = (low + high) / 2; 14 if (nums[mid] < target) 15 low = mid + 1; 16 else{ 17 ind = nums[mid] == target ? mid : ind; 18 high = mid - 1; 19 } 20 } 21 return ind; 22 } 23 24 public int lastBinarySearch(int[] nums, int target) { 25 int low = 0, high = nums.length - 1; 26 int ind = -1; 27 while (low <= high) { 28 int mid = (low + high) / 2; 29 if (nums[mid] > target) 30 high = mid - 1; 31 else{ 32 ind = nums[mid] == target ? mid : ind; 33 low = mid + 1; 34 } 35 } 36 return ind; 37 } 38 39 public int specialBinarySearch(int[] nums, int target, boolean isFirst) { 40 int low = 0, high = nums.length - 1; 41 int ind = -1; 42 while (low <= high) { 43 int mid = (low + high) / 2; 44 if (nums[mid] < target) 45 low = mid + 1; 46 else if (nums[mid] > target) 47 high = mid - 1; 48 else { 49 ind = mid; 50 high = isFirst ? mid - 1 : high; 51 low = !isFirst ? mid + 1 : low; 52 } 53 } 54 return ind; 55 } 56 }
这里还写了一个最终版本specialBinarySearch,将两种情况合并到一起判断。是不是和原来的基础版很接近?