二分查找 && 边界问题

26 阅读1分钟
  • 前言:该题解为个人总结,仅供参考,对初学习二分的伙伴并不友好原理很简单,细节是魔鬼推荐参考网站

常用api:sort.SearchInts(nums, target) <返回值为目标元素下标 or 目标元素该插入的下标

场景1:无重复.有序数组中查找元素

    // 1.调用api实现
    func main(){
        nums := []int{1, 2, 3, 4, 5}
        target := 9
        index := sort.SearchInts(nums, target)
        if index < len(nums) && target == nums[index] {
            fmt.Println(index)
        } else {
            fmt.Println(-1)
        }
    }

    // 2.手动实现<返回值为目标元素下标 or 目标元素该插入的下标>
    func searchRangeLeft(nums []int, target int) int {
        length := len(nums)
        i := 0
        j := length

        for i < j {
            mid := i + (j-i)/2
            if nums[mid] == target {
                j = mid
            } else if nums[mid] > target {
                j = mid
            } else if nums[mid] < target {
                i = mid + 1
            }
        }

        return i
    }

场景2:可重复.有序数组中查找左边界

    // 1.调用api实现
    func main(){
        nums := []int{1, 2, 2, 2, 2, 3, 4, 5}
        target := 9
        index := sort.SearchInts(nums, target)
        if index < len(nums) && target == nums[index] {
            fmt.Println(index)
        } else {
            fmt.Println(-1)
        }
    }
    // 2.手动实现<返回值为目标元素下标 or 目标元素该插入的下标>
    func searchRangeLeft(nums []int, target int) int {
        length := len(nums)
        i := 0
        j := length

        for i < j {
            mid := i + (j-i)/2
            if nums[mid] == target {
                j = mid
            } else if nums[mid] > target {
                j = mid
            } else if nums[mid] < target {
                i = mid + 1
            }
        }

        return i
    }


场景3:可重复.有序数组中查找右边界

    // 1.调用api实现
    func main(){
        nums := []int{1, 2, 2, 2, 2, 3, 4, 5}
        target := 2
        index := sort.SearchInts(nums, target+1) - 1
        if index < len(nums) && target == nums[index] {
            fmt.Println(index)
        } else {
            fmt.Println(-1)
        }
    }
    // 2.手动实现<返回值为目标元素下标 or 目标元素该插入的下标>
    func searchRangeRight(nums []int, target int) int {
        length := len(nums)
        i := 0
        j := length

        for i < j {
            mid := i + (j-i)/2
            if nums[mid] == target {
                i = mid + 1
            } else if nums[mid] > target {
                j = mid
            } else if nums[mid] < target {
                i = mid + 1
            }
        }

        return i - 1
    }