关于二分查找的一些理解

二分查找算法

闭区间写法

对于闭区间写法来说,返回的left是第一个找到的target对应的下标,返回的right是left-1,因此一般返回left,如果target > max(nums),则会返回len(nums),若target < min(nums),则会返回0,若min(nums) < target< max(nums),但是不存在数组中,则会返回第一个大于此数的下标

// 闭区间写法
func lowerBoundBothClosedInterval(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		mid := left + (right-left)/2
		if nums[mid] < target {
			left = mid + 1
		} else {
			right = mid - 1
		}
	}
	return left
}

左闭右开区间

对于左闭右开区间写法来说,返回的left是第一个找到的target对应的下标,返回的right等于left,因此随便返回哪个,如果target > max(nums),则会返回len(nums),若target < min(nums),则会返回0,若min(nums) < target< max(nums),但是不存在数组中,则会返回第一个大于此数的下标

// 左闭右开区间
func lowerBoundLeftClosedRightOpen(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
}

开区间写法

对于开区间写法来说,返回的right是第一个找到的target对应的下标,返回的left==left-1,因此返回right,如果target > max(nums),则会返回len(nums),若target < min(nums),则会返回0,若min(nums) < target< max(nums),但是不存在数组中,则会返回第一个大于此数的下标

func lowerBoundBothOpenInterval(nums []int, target int) int {
	left, right := -1, len(nums)
	for left+1 < right {
		mid := left + (right-left)/2
		if nums[mid] < target {
			left = mid
		} else {
			right = mid
		}
	}
	return right
}

tip

如果想要在例如{1,2,3,3,3,3,4}的数组中找到最右边的3怎么办?
我们只需要将target改为3 + 1,然后将答案-1即可

便于记忆方法

闭区间对应更加合理的left和right范围,因此所有闭区间的地方都会在合理的下标中,如left=0,right=len(nums)-1,但是变成开区间后,左会更左,右会更右。在循环中,凡是闭区间left = mid + 1 , right = mid - 1,否则left = mid , right = mid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值