题目重点:不能拼接木头,切出至少K段,求正整数段长最大值。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 木长为非负整数,K>0;无锯缝损耗,剩余段可丢弃。
- 每段必须来自一根木头;不可行返回0。浮点长度是另一合同。
解题路线
- 验证候选L的可行性:第w根最多切floor(w/L)段,总数≥K即足够。
- L越大,段数只会减少,所以可行整数构成前缀。维护闭区间[lo,hi],可行时记答案并往右,不可行时往左。
- 上界max(woods),因为不能跨木头拼接。可改为min(max,sum//K);sum//K仅是上界,不代表可行。
手动走一遍
woods=[5,9,7],K=5:L=4得到1+2+1=4段,不可行;L=3得到1+3+2=6段,可行,答案3。woods=[1,1],K=3没有正长度可行,返回0;K=1答案最大木长。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def max_length(woods, k):
if k <= 0 or any(type(w) is not int or w < 0 for w in woods):
raise ValueError("nonnegative integer lengths and positive k required")
lo, hi = 1, max(woods, default=0)
answer = 0
while lo <= hi:
mid = (lo + hi) // 2
count = sum(w // mid for w in woods)
if count >= k:
answer, lo = mid, mid + 1
else:
hi = mid - 1
return answer
复杂度
O(n log W)时间、O(1)额外空间,W为最大长度;log来自值域而非数组元素数。Python整数算术位成本另计。
易错点与追问
容易失分的边界
- 不要计算w//0;答案0不能作为验证长度。
- 浮点二分不能沿用lo=mid+1,应固定迭代数或绝对/相对精度。
继续深挖
- 如果锯缝宽d,段数如何由tL+(t−1)d≤w推导?
- 实数合同怎样输出可证误差区间,并处理临界浮点舍入?
