[M二分] lc1760. 袋子里最少数目的球(二分答案+数学推导+GoLang使用技巧)

文章目录

    • [1. 题目来源](#1. 题目来源)
    • [2. 题目解析](#2. 题目解析)

1. 题目来源

链接:1760. 袋子里最少数目的球

题单:

  • 待补充

2. 题目解析

思路:

  • 看题意求最大、最小,很明显的二分答案,直接去二分满足条件下的最终袋子中球的个数。
  • 二段性思考 :
    • 如果最终袋子中球都是 1 个的话,那么袋子肯定很多,操作次数就非常多。
    • 如果最终袋子中球都可以装很多的时候,那么一开始都不用二分,操作次数就是 0。
    • 故,二分的边界点就是这个操作次数。那么操作边界就是最终袋子中能装的球的个数,即 [1, max{nums[0~n-1]}。
  • 操作次数思考:
    • 如果二分答案袋子中的球至多可装 y 个情况下。
    • 那么原有袋子球在 [1,y] 的操作次数是 0,在 [y+1, 2y] 的操作次数是 1。
    • 数学归纳来看,numsi 的操作次数就是 n u m s i − 1 y {\frac{numsi-1}{y}} ynumsi−1

综上,本题实际上不是很难,值得一提的是:

  • 关于这个操作次数的推导,可以看看灵神那边针对边界、针对上取整、下取整的数学推导,更为严谨。可以看看官解中针对 1~y、y+1 ~2y 这种分段的判断,更为直观。
  • 最近拿 GoLang 写算法,比如二分,比如求 slice 中的最大元素,都有现成的库函数待学习。见这个博主的博文整理,挺不错的:【Go基础】Go算法常用函数整理

坑点:

  • C++ 选手记得开 long long 不然会爆...
  • 1000000000,1000000000,1000000000

    1000000000
    这个数据,最终结果是 3,但 cnt 的累计就很多很多超过 int 上限了...

  • 时间复杂度 : O ( n ) O(n) O(n)
  • 空间复杂度 : O ( 1 ) O(1) O(1)

go 复制代码
func minimumSize(nums []int, maxOperations int) int {
    check := func(k int) bool {
        cnt := 0
        for _, v := range nums {
            cnt += (v - 1) / k
        }
        return cnt > maxOperations
    }

    l, r := 1, slices.Max(nums)
    for l < r {
        mid := (l + r) / 2
        if check(mid) {
            l = mid + 1
        } else {
            r = mid
        }
    }

    return l
}

库函数写法:

go 复制代码
func minimumSize(nums []int, maxOperations int) int {
	max := 0
	for _, x := range nums {
		if x > max {
			max = x
		}
	}
	return sort.Search(max, func(y int) bool {
		if y == 0 {
			return false
		}
		ops := 0
		for _, x := range nums {
			ops += (x - 1) / y
		}
		return ops <= maxOperations
	})
}
相关推荐
Nil2082 小时前
leetcode 300最长递增子序列
算法·leetcode·职场和发展
yi0113 小时前
LeetCode 424. 替换后的最长重复字符|不定长滑动窗口:如何判断窗口是否合法?
笔记·python·算法·leetcode·双指针·滑动窗口
All for pursuit.4 小时前
【动态规划-11】279.完全平方数
数据结构·c++·算法·leetcode·动态规划
yi0115 小时前
LeetCode 3. 无重复字符的最长子串|不定长滑动窗口:什么时候更新最大值?
笔记·python·算法·leetcode·双指针·滑动窗口
y1su5 小时前
Leetcode 单调栈模板
java·开发语言·数据结构·算法·leetcode
longlongzihan17 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
yi01117 小时前
LeetCode 643. 子数组最大平均数 I|从暴力枚举到滑动窗口
人工智能·笔记·python·算法·leetcode·滑动窗口
java_nnnn19 小时前
LeetCode刷题双指针(有效三角形的个数+三数之和)Java
算法·leetcode·职场和发展
All for pursuit.20 小时前
【动态规划-6】96.不同的二叉搜索树
数据结构·c++·算法·leetcode·动态规划
All for pursuit.1 天前
【并查集-2】399.除法求值
数据结构·c++·算法·leetcode