[Leetcode Weekly Contest]173
链接:LeetCode
[Leetcode]5319.删除回文子序列
给你一个字符串 s,它仅由字母 'a' 和 'b' 组成。每一次删除操作都可以从 s 中删除一个回文 子序列。返回删除给定字符串中所有字符(字符串为空)的最小删除次数。
注意这里,「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。
「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一个回文。
这道题关键在于“审题”,当发现字符串仅有字母 'a' 和 'b' 组成,那么我们联想到,删除给定字符串中所有字符(字符串为空)的最小删除次数只有三种情况:
- 0种,即字符串为空
- 1种,即字符串本身为回文
- 2种,即其他情况。因为当字符串仅有字母 'a' 和 'b' 组成,则我们可以将所有包含a的子序列提取出来删除,再将所有b的子序列删除,此时只需要两次就实现了删除所有字符。
class Solution:
def removePalindromeSub(self, s: str) -> int:
if not s:
return 0
if s == s[::-1]:
return 1
return 2
[Leetcode]5320.餐厅过滤器
给一个餐馆信息数组 restaurants,其中 。你必须使用以下三个过滤器来过滤这些餐馆信息。
其中素食者友好过滤器 veganFriendly 的值可以为 true 或者 false,如果为 true 就意味着你应该只包括 veganFriendlyi 为 true 的餐馆,为 false 则意味着可以包括任何餐馆。此外,我们还有最大价格 maxPrice 和最大距离 maxDistance 两个过滤器,它们分别考虑餐厅的价格因素和距离因素的最大值。
过滤后返回餐馆的 id,按照 rating 从高到低排序。如果 rating 相同,那么按 id 从高到低排序。简单起见, veganFriendlyi 和 veganFriendly 为 true 时取值为 1,为 false 时,取值为 0 。
当理解题意之后,代码也就很简单了,这不过是一道普通的业务理解题:
class Solution:
def filterRestaurants(self, restaurants: List[List[int]], veganFriendly: int, maxPrice: int, maxDistance: int) -> List[int]:
if veganFriendly:
restaurants = [x for x in restaurants if x[2]==1]
restaurants = [x for x in restaurants if x[3]<=maxPrice and x[4]<=maxDistance]
restaurants.sort(key=lambda x:[-x[1],-x[0]])
return [x[0] for x in restaurants]
[Leetcode]5321.阈值距离内邻居最少的城市
有个城市,按从到编号。给你一个边数组,其中 代表 和 两个城市之间的双向加权边,距离阈值是一个整数。
返回能通过某些路径到达其他城市数目最少、且路径距离最大为的城市。如果有多个这样的城市,则返回编号最大的城市。
考察点在于寻找每个城市间的最短路径,常用的有弗洛伊德算法:
class Solution:
def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
matrix = [[float('inf') for j in range(n)] for i in range(n)]
for from_,to_,weight_ in edges:
matrix[from_][to_] = weight_
matrix[to_][from_] = weight_
for i in range(n):
matrix[i][i] = 0
res = self.floyd(matrix,n)
ids = [0 for _ in range(n)]
for i in range(n):
ids[i] = len([x for x in res[i] if x<=distanceThreshold])
mn = min(ids)
res = [i for i,n in enumerate(ids) if n==mn]
return max(res)
# F算法
def floyd(self,matrix,n):
for i in range(n):
for j in range(n):
for k in range(n):
matrix[j][k] = min(matrix[j][k], matrix[j][i] + matrix[i][k])
return matrix
[Leetcode]5322.工作计划的最低难度
你需要制定一份天的工作计划表。工作之间存在依赖,要想执行第项工作,你必须完成全部项工作。
你每至少需要完成一项任务。工作计划的总难度是这天每一天的难度之和,而一天的工作难度是当天应该完成工作的最大难度。
给你一个整数数组和一个整数,分别代表工作难度和需要计划的天数。第项工作的难度是。返回整个工作计划的最小难度。如果无法制定工作计划,则返回 -1 。
这是一道动态规划题,难度在于两个:构造动态转移方程以及状态的初始化。
先构造动态转移方程,我们令表示计划天完成项工作的最小难度,考察的值,有以下可能:
- 当,即当前项比前面一项大,则我们考察每一个前面的,令,其中preMax代表的最大值,也就是说,我们把的工作在一天完成,那么这一天的日工作量也就是其中的最大难度,再加上前面的天的最小难度,也就是在当前值下的最小难度。遍历k即可得到全局最小难度。
- 当,即当前项比前面一项小,那么我们可以将当期项单独在一天完成(也就是天完成项的最小难度加上当前项难度,即),也可以把当前项与前面项共同完成(由于比前面项小,所以此时不影响的值),因此转移式如下:
总的来说,考察天完成项工作的最小难度,当前项工作只有可能单独完成或者是跟前面项一起完成,考虑这两种情况即可。
另外,要特别考虑状态的初始化,当时,;否则,当 or or 时,
整体代码如下:
class Solution:
def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
n = len(jobDifficulty)
if n < d:
return -1
if n == d:
return sum(jobDifficulty)
dp = [[float('inf') for j in range(n+1)] for i in range(d+1)]
dp[0][0] = 0
for i in range(1,d+1):
for j in range(i,n+1):
if i == j:
dp[i][j] = sum(jobDifficulty[:j])
elif jobDifficulty[j-1] <= jobDifficulty[j-2]:
dp[i][j] = min(dp[i][j-1],dp[i-1][j-1]+jobDifficulty[j-1])
else:
preMax = jobDifficulty[j-1]
for k in reversed(range(1,j+1)):
preMax = max(preMax,jobDifficulty[k-1])
dp[i][j] = min(dp[i][j],dp[i-1][k-1]+preMax)
return dp[-1][-1]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)