Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

整体思路刚好与 searchLeft 相反,为收缩左边届 ——

方法二:利用 leftBound

上一题的 searchLeft 中其实隐含了一个「找到 >= target 的最小索引」的方案(称为 leftBound

...

Code Block
languagego
func searchRange(nums []int, target int) []int {
    l := searchLeft(nums, target)
    if l == -1 {
        return []int{-1, -1}
    }
    r := searchRight(nums, target)
    
    return []int{l, r}
}

func searchLeft(nums []int, target int) int {
    x := leftBound(nums, target)
    
    if x >= len(nums) || nums[x] != target {
        return -1
    }
    
    return x
}

func searchRight(nums []int, target int) int {
    // 寻找 target 的右边界 = 寻找 >= target+1 的元素的左边届-1
    x := leftBound(nums, target + 1) - 1
    
    // 注意此时 target+1 过小时,x = -1
    if x == -1 || nums[x] != target {
        return -1
    }
    
    return x
}

// 返回  >= target 的最小索引
func leftBound(nums []int, target int) int {
    left, right := 0, len(nums)
    
    for left < right {
        mid := left + (right - left) / 2
        
        if nums[mid] >= target {
            right = mid
        } else {
            left = mid + 1
        }
    }
    
    return right
}

LCCN LCR 172. 统计目标成绩的出现次数

https://leetcode.cn/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/description/

本题与上一题几乎一样(只有返回值不一样)

采用 rightBound 完成:

Code Block
languagego
func countTarget(scores []int, target int) int {
    l := searchLeft(scores, target)
    if l == -1 {
        // score not exist
        return 0
    }
    r := searchRight(scores, target)
    return r-l+1
}

func searchLeft(nums []int, target int) int {
    x := rightBound(nums, target-1) + 1
    if x >= len(nums) || nums[x] != target {
        return -1
    }
    return x
}

func searchRight(nums []int, target int) int {
    x := rightBound(nums, target)
    if x < 0 || nums[x] != target {
        return -1
    }
    return x
}

// 返回 <= target 的最大索引
func rightBound(nums []int, target int) int {
    left, right := 0, len(nums)

    for left < right {
        mid := left + (right - left) / 2

        if nums[mid] <= target {
            left = mid + 1
        } else{
            right = mid
        }
    }

    return left - 1
}

LC.278 First Bad Version 第一个错误的版本

...