刷题-两球之间的距离最短

一、解题思路

题目链接
其实依然是使用二分来解,只不过这次的二分并不是数组下标的二分,而是每个桶之间距离的二分。
审题后不难理解,最终答案肯定在相邻桶最短距离 ~ 两头桶之间的距离 之间。我们在这个范围进行二分即可。
最后时间复杂度应该是O(Nlog(N)),严格来说是O(arrLen * log(maxDistance))

二、代码

1、check:负责检查指定距离是否能实现,依次遍历所有桶,看最后球是否能放满即可。

func check(position []int, ballNum int, minLen int) bool {
	// 起始位置肯定要放球
	ballNum--
	currentPos := 1
	lastPos := 0
	for ballNum > 0 && currentPos < len(position) {
		if position[currentPos]-position[lastPos] >= minLen {
			lastPos = currentPos
			ballNum--
		}
		currentPos++
	}
	if 0 == ballNum {
		return true
	} else {
		return false
	}
}

2、二分遍历距离
保证for 循环能退出就行

func MaxDistance(position []int, m int) int {
	sort.Ints(position)

	// 开始二分搜索
	retDis := 0
	maxDis := (position[len(position)-1] - position[0]) / (m - 1)
	minDis := math.MaxInt64
	for index := 0; index < len(position)-1; index++ {
		currentDis := position[index+1] - position[index]
		if minDis > currentDis {
			minDis = currentDis
		}
	}

	leftDis, rightDis := minDis, maxDis
	for leftDis <= rightDis {
		midDis := (leftDis + rightDis) / 2
		if check(position, m, midDis) {
			leftDis = midDis + 1
			retDis = midDis
		} else {
			rightDis = midDis - 1
		}
	}
	return retDis
}

三、总结

其实二分搜索使用场景还是挺多的,不要仅仅纠结于数组下标。需要多做题多总结。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值