「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
翻译一下题意, m个男生一起上厕所(小号), 怎样才能最大程度的避免尴尬.
——leetcode此题热评
前言
大家好,我是一条,欢迎来到我的算法频道。
只做有趣的算法题,只为面试写算法。
Question
1552. 两球之间的磁力
难度:中等
Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。
已知两个球如果分别位于 x 和 y ,那么它们之间的磁力为 |x - y| 。
给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。
示例 1:
输入:position = [1,2,3,4,7], m = 3 输出:3 解释:将 3 个球分别放入位于 1,4 和 7 的三个篮子,两球间的磁力分别为 [3, 3, 6]。最小磁力为 3 。我们没办法让最小磁力大于 3 。
Solution
热评把这道题翻译的很形象。
问题是求最小值最大,那应该怎么放球?——平均放,也就是把位置分散开。
不难想到和二分查找有关
二分模板
先补充两个二分模板。
模板1:
boolean check(int x) {}
int search(int left, int right) {
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) right = mid;
else left = mid + 1;
}
return left;
}
模板2:
boolean check(int x) {}
int search(int left, int right) {
while (left < right) {
int mid = (left + right + 1) >> 1;
if (check(mid)) left = mid;
else right = mid - 1;
}
return left;
}
做二分题时,按照以下步骤:
- 写出循环条件:
while (left < right),注意是left < right,而非left <= right; - 循环体内,无脑写出
mid = (left + right) >> 1; - 实现
check()函数,想一下究竟要用left = mid还是right = mid; - 如果
left = mid,那么无脑写出 else 语句right = mid - 1,并且在 mid 计算时补充 +1,即mid = (left + right + 1) >> 1; - 如果
right = mid,那么无脑写出 else 语句left = mid,并且不需要更改 mid 的计算; - 循环结束时,left 与 right 相等。
本题题解
先排序,然后二分枚举相邻两球之间的间距,只需要统计当前间距下能放下多少个小球,记为 cnt,若 cnt >= m,说明此间距符合条件。继续二分查找,最终找到符合条件的最大间距。
Code
/**
* @author 一条coding
*/
最后
点赞,点赞,还TMD是点赞!