202期比赛题目解法
5489. 两球之间的磁力
在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n
个空的篮子,第 i
个篮子的位置在 position[i]
,Morty 想把 m
个球放到这些篮子里,使得任意两球间 最小磁力 最大。
已知两个球如果分别位于 x
和 y
,那么它们之间的磁力为 |x - y|
。
给你一个整数数组 position
和一个整数 m
,请你返回最大化的最小磁力。
示例 1:
1 | 输入:position = [1,2,3,4,7], m = 3 |
示例 2:
1 | 输入:position = [5,4,3,2,1,1000000000], m = 2 |
提示:
n == position.length
2 <= n <= 10^5
1 <= position[i] <= 10^9
- 所有
position
中的整数 互不相同 。 2 <= m <= position.length
解答
思路
step 1.
首先我们对position排序,得到按顺序排列的篮子step 2.
最小的磁力:就是这些m个篮子间那个最短的距离
最大的磁力:就是把最大间距(position的尾减头)平均分,保证篮子间的距离都一样
所以能取到的磁力范围必定落在【最小磁力,最大磁力】这个区间上step 3.
可以从小往大找,也可以从大往小找,也可以使用二分法从中间开始找,这种时间复杂度应该是最低的
所谓的磁力其实就是间隔,假设我们区间中间的磁力是mid,要对间隔 mid 的放球法做出判断,看看能不能这样放
验证的方法是:从第一个篮子开始逐个放球,如果下一个篮子距离上一个篮子没有mid那么远,就选后面的一个篮子,直至放球的篮子间达到距离mid的要求。如果球全放完了,证明成功;如果有球无法按要求放了则证明失败step 4.
如果step 3中的验证成功,我们可以试试更大的距离;如果失败,则用更小的距离。更大更小的距离也是通过二分法选择,直至找到那个最大的距离
[以上来自力扣题解]
基本代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38func maxDistance(position []int, m int) int {
sort.Ints(position)
//1. 获得最大的距离
hi := (position[len(position)-1] - position[0]) / (m - 1)
//2. 最小的距离是 1
lo := 1
ans := 1
//3. 距离一定在 最大和最小之间 ,使用二分法寻找
for lo <= hi {
mid := lo + (hi-lo)/2
//4. 判断找到的位置 是否能够把剩余的球放下
//5. 如果从前半段能够把球放下,则继续把 mid 向后移动,尝试更大的范围
//6. 同理如果前半段放不下,则需要压缩 mid 的值
if judge(position, mid, m) {
ans = mid
lo = mid + 1
} else {
hi = mid - 1
}
}
return ans
}
func judge(position []int, mid, m int) bool {
count := 1
i := 0
//判断在 position 中,放 m 个求能否放下。
for j := 1; j < len(position); j++ {
if position[j]-position[i] >= mid {
i = j
count++
if count >= m {
return true
}
}
}
return false
}
5490. 吃掉 N 个橘子的最少天数
厨房里总共有 n
个橘子,你决定每一天选择如下方式之一吃这些橘子:
- 吃掉一个橘子。
- 如果剩余橘子数
n
能被 2 整除,那么你可以吃掉n/2
个橘子。 - 如果剩余橘子数
n
能被 3 整除,那么你可以吃掉2*(n/3)
个橘子。
每天你只能从以上 3 种方案中选择一种方案。
请你返回吃掉所有 n
个橘子的最少天数。
示例 1:
1 | 输入:n = 10 |
示例 2:
1 | 输入:n = 6 |
示例 3:
1 | 输入:n = 1 |
示例 4:
1 | 输入:n = 56 |
提示:
1 <= n <= 2*10^9
解题思路
递归思路:n%2
代表如果吃掉 1/2 的时候,需要吃掉 1 的天数n%3
带边需要吃掉 2/3 多出来的 1 的个数。
代码
1 | func minDays(n int) int { |