Golang实现二分查找算法

二分查找范例模板

1. 寻找目标值

  • 搜索区间(search space): [left, right],可分割为[left, mid - 1]与[mid + 1, right]
  • 循环结束条件: left == right + 1
  • 循环结束时搜索区间取值: [right + 1, right],此时搜索区间为空
  • mid值大于目标值,右边界向左收缩,反之向右扩张
  • 寻得目标值时立即返回该值在数组中的index,反之返回-1
func binarySearch(arr []int, target int) int{
	// 搜索区间 [left, right]
	left := 0 				// 数组左边界的下标index
	right := len(arr)-1 	// 数组右边界的下标index
	// 循环条件,左边界小于等于右边界
	for left <= right{
		mid := left+(right-left)>>1
		// mid值大于目标值,右边界向左收缩
		if arr[mid] > target {
			right = mid -1
		}
		// mid值小于目标值,左边界向右扩张
		else if arr[mid]<target{
			left = mid +1
		}
		// 符合条件时,随即返回其index
		else{
			return mid
		}
	}
	return -1
}

2. 寻找目标值的左侧边界

  • 搜索区间: [left, right),可分割为[left, mid) 或 [mid + 1, right)
  • 循环结束条件: left == right
  • 循环结束时搜索区间取值: [right, right]
  • 当mid值等于目标值时,无需即时返回该mid,如[1, 2, 2, 2, 3]
  • 此时将右侧边界等于mid,right = mid,继续向左收缩,锁定左侧边界值
func binarySearch(arr []int, target int) int{
	// 搜索区间左闭右开,[left, right)
	left := 0 // 左边界,数组中的最大值元素
	right := len(arr) 	// 右边界,数组长度
	// 循环条件,左边界小于右边界
	for left < right{
		mid := left+(right-left)>>1
		// mid值大于目标值,右边界向左收缩
		if arr[mid] > target {
			right = mid	//视情况而减1
		}
		// mid值小于目标值,左边界向右扩张
		else if arr[mid]<target{
			left = mid +1
		}
		// 符合条件时不立即返回,继续收缩右侧边界,锁定左侧边界
		else{
			right = mid
		}
	}
	return left
}

3. 寻找目标值的右侧边界

  • 当寻找到目标值时,无需即时返回,而是扩张左侧边界,使得区间向右收缩,锁定右侧边界
  • 循环终止条件: left == right, [right,right]
  • 循环结束时,边界值被更新为left = mid +1,此时left-1的index才可能是target值,所以右侧边界值需减1
func binarySearch(arr []int, target int) int{
	// 搜索区间左闭右开,[left, right)
	left := 0 // 左边界,数组中的最大值元素
	right := len(arr) 	// 右边界,数组长度
	// 循环条件,左边界小于右边界
	for left < right{
		mid := left+(right-left)>>1
		// mid值大于目标值,右边界向左收缩
		if arr[mid] > target {
			right = mid
		}
		// mid值小于目标值,左边界向右扩张
		else if arr[mid]<target{
			left = mid +1
		}
		// 符合条件时不立即返回,继续扩张左侧下界,锁定右侧边界
		else{
			left = mid + 1
		}
	}
	return left-1
}

参考博文

posted @ 2020-07-31 16:07  litchi99  阅读(303)  评论(0编辑  收藏  举报