学习来源:
leetcode官方题解
评论区大佬的题解
1552 两球之间的磁力
题意理解:给定position
数组,从中选取m
个,使得这m
个数据中,任意两个数的差值的最小值最大。比如:position = [1,2,3,6]
,m = 3
。那么所有的选取情况为[1,2,3]
、[1,2,6]
、[2,3,6]
、[1,3,6]
。每种情况下任意两数差值的最小值为1
、1
、1
、2
。那么最终选取为:[1,3,6]
,答案为:2
。
算法思想:结合二分查找的暴力测试(多见题型,才能打开思路),每次选取一个可能的最小磁力值,测试验证是否可以满足题意,直到找出最大的最小磁力值。难点在于边界值的确定,最小磁力值的左边界很好确定,遍历一遍排序后的position数组即可,对于右边界,因为有m
个球,所以存在m-1
个缝隙。给定的position
数组中的最大间距 max_magnetic = position[-1] - position[0]
,因此可以计算得出,右边界为:max_magnetic // (m-1)
。
# 判断当前最小磁力值是否符合条件
def judge(length,position,m):
res = 0
lens = len(position)
l = r = 0
while r < lens:
'''
若position[r] - position[l]大于等于当前最小磁力值,则在position[r]处放置一个球
更新索引,继续向下搜索下一个球的位置
'''
if position[r] - position[l] >= length:
l = r
r += 1
res += 1
else:
r += 1
if res >= m - 1:
return True
else:
return False
lens = len(position)
position.sort()
min_magnetic = float("inf")
# 确定最小边界
for i in range(lens-1):
min_magnetic = min(min_magnetic, position[i+1]-position[i])
# 计算最大边界
max_magnetic = (position[-1] - position[0])//(m-1)
# 二分查找
while min_magnetic<=max_magnetic:
mid_magnetic = (min_magnetic+max_magnetic)//2
if judge(mid_magnetic,position,m):
min_magnetic = mid_magnetic + 1
else:
max_magnetic = mid_magnetic - 1
return min_magnetic - 1
1553 吃掉N个橘子最少的天数
题意理解:给定N
个橘子,每次可以吃1
个;若N
为偶数,则可以选择吃N/2
个;若N
可以被3
整除,则可以选择吃2*(N/3)
个。求最快多少次可以吃完。
算法分析:DFS
,朴素dfs算法因为重复计算会超时,需要改进。当N <= 3
时,答案显而易见,那么当N > 3
时,为了尽快吃完,可以先吃掉i
个,使得N-i
可以被3
或者2
整除。
def dfs(i,dp):
if i == 0:
return 0
if i == 1:
return 1
if i == 2 or i == 3:
return 2
# 若已经计算过,则直接返回
if i in dp:
return dp[i]
# 返回使得 剩余橘子可以被3整除的结果 和 可以被2整除的结果 的较小值,+1 是计算本次吃橘子的操作
dp[i] = 1 + min(dfs(i//2,dp)+i%2, dfs(i//3,dp)+i%3)
return dp[i]
# 存储已经计算的完成天数
dp = dict()
return dfs(n,dp)