给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]
进阶:

  • 你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?


    示例 1:

    1. 输入:nums = [5,7,7,8,8,10], target = 8
    2. 输出:[3,4]

    示例 2:

    1. 输入:nums = [5,7,7,8,8,10], target = 6
    2. 输出:[-1,-1]

    示例 3:

    1. 输入:nums = [], target = 0
    2. 输出:[-1,-1]


    提示:

  • 0 <= nums.length <= 10

  • -10 <= nums[i] <= 10
  • nums 是一个非递减数组
  • -10 <= target <= 10

    解法一:二分查找

    二分查找攻略

    1. func searchRange(nums []int, target int) []int {
    2. var low, high, left, right int
    3. left, right = 0, len(nums)-1
    4. for left <= right {
    5. mid := left + (right-left)>>1
    6. if nums[mid] >= target {
    7. right = mid - 1
    8. } else {
    9. left = mid + 1
    10. }
    11. }
    12. if left >= len(nums) || nums[left] != target {
    13. low = -1
    14. } else {
    15. low = left
    16. }
    17. left, right = 0, len(nums)-1
    18. for left <= right {
    19. mid := left + (right-left)>>1
    20. if nums[mid] > target {
    21. right = mid - 1
    22. } else {
    23. left = mid + 1
    24. }
    25. }
    26. if right < 0 || nums[right] != target {
    27. high = -1
    28. } else {
    29. high = right
    30. }
    31. return []int{low, high}
    32. }

优化下:
image.png
这里 right 的结果为什么要 -1?
可以解释下,因为循环退出的条件是 left <= right 也就是说这时候 left = right + 1 ,所以按照上文的逻辑,本应返回 right ,这里返回了 left 所以需要 -1

  1. func searchRange(nums []int, target int) []int {
  2. left, right := binarySearch(nums, target, true), binarySearch(nums, target, false)-1
  3. if left < len(nums) && nums[left] == target && right >= 0 && nums[right] == target {
  4. return []int{left, right}
  5. }
  6. return []int{-1, -1}
  7. }
  8. func binarySearch(nums []int, target int, isLower bool) int {
  9. left, right := 0, len(nums)-1
  10. for left <= right {
  11. mid := left + (right-left)>>1
  12. if (isLower && nums[mid] >= target) || nums[mid] > target {
  13. right = mid - 1
  14. } else {
  15. left = mid + 1
  16. }
  17. }
  18. return left
  19. }

直接写出来这种可能不太好写,可以先从第一种往这种靠