2021-09-21:给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。要求:设计并实现时间复杂度为 O(log n) 的算法。

福大大 答案2021-09-21:

二分法。
时间复杂度:O(N)。
空间复杂度:O(1)。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
    arr := []int{1, 2, 3, 3, 4, 6}
    target := 3
    ret := searchRange(arr, target)
    fmt.Println(ret)
    ret = searchRange2(arr, target)
    fmt.Println(ret)
}

func searchRange(nums []int, target int) []int {
    if len(nums) == 0 {
        return []int{-1, -1}
    }
    L := lessMostRight(nums, target) + 1
    if L == len(nums) || nums[L] != target {
        return []int{-1, -1}
    }
    return []int{L, lessMostRight(nums, target+1)}
}

func lessMostRight(arr []int, num int) int {
    L := 0
    R := len(arr) - 1
    M := 0
    ans := -1
    for L <= R {
        M = L + (R-L)>>1
        if arr[M] < num {
            ans = M
            L = M + 1
        } else {
            R = M - 1
        }
    }
    return ans
}

func searchRange2(nums []int, target int) []int {
    if len(nums) == 0 {
        return []int{-1, -1}
    }
    lv := NearestIndex(nums, target)
    rv := NearestIndex2(nums, target)
    if lv == -1 {
        return []int{-1, -1}
    }
    if rv == -1 {
        return []int{-1, -1}
    }
    if lv > rv {
        return []int{-1, -1}
    }
    return []int{lv, rv}
}

// 在arr上,找满足>=value的最左位置
func NearestIndex(arr []int, v int) int {
    L := 0
    R := len(arr) - 1
    index := -1 // 记录最左的对号
    for L <= R {
        mid := L + (R-L)>>1
        if arr[mid] >= v {
            index = mid
            R = mid - 1
        } else {
            L = mid + 1
        }
    }
    return index
}

// 在arr上,找满足<=value的最右位置
func NearestIndex2(arr []int, v int) int {
    L := 0
    R := len(arr) - 1
    index := -1 // 记录最右的对号
    for L <= R {
        mid := L + (R-L)>>1
        if arr[mid] <= v {
            index = mid
            L = mid + 1
        } else {
            R = mid - 1
        }
    }
    return index
}

执行结果如下:
图片


左神java代码