github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/dichotomy/dichotomy.go (about)

     1  package dichotomy
     2  
     3  // 1。能找到存在于数组中,必然是 middle index
     4  // 2. 不能找到,不存在于数组中,需要返回其应该被插入的位置
     5  
     6  func BinarySearchLastIndex(nums []int, target int) int {
     7  	l, r := 0, len(nums)-1
     8  	for l <= r {
     9  		mid := (l + r) >> 1
    10  		if nums[mid] > target {
    11  			r = mid - 1
    12  		} else if nums[mid] < target {
    13  			l = mid + 1
    14  		} else {
    15  			if mid == len(nums)-1 || nums[mid]-nums[mid+1] != 0 {
    16  				// 这个方式就是找到最后一个等同于目标值的索引位置
    17  				return mid
    18  			}
    19  			// 这样做是为了让相等范围进一步缩小,最后让 middle 值定位到最后的且等同于目标值的索引位置
    20  			l = mid + 1
    21  		}
    22  	}
    23  	// 没找到,返回插入的位置,以负数的形式
    24  	// 获取到结果之后需要转换
    25  	return -l - 1
    26  }
    27  
    28  func BinarySearchFirstIndex(nums []int, target int) int {
    29  	l, r := 0, len(nums)-1
    30  	for l <= r {
    31  		mid := (l + r) >> 1
    32  		if nums[mid] > target {
    33  			r = mid - 1
    34  		} else if nums[mid] < target {
    35  			l = mid + 1
    36  		} else {
    37  			if mid == 0 || nums[mid]-nums[mid-1] != 0 {
    38  				// 这个方式就是找到第一个等同于目标值的索引位置
    39  				return mid
    40  			}
    41  			// 这样做是为了让相等范围进一步缩小,最后让 middle 值定位到第一个且等同于目标值的索引位置
    42  			r = mid - 1
    43  		}
    44  	}
    45  	// 没找到,返回插入的位置,以负数的形式
    46  	// 获取到结果之后需要转换
    47  	return -l - 1
    48  }