返回
LeetCode:一路加油站
IOS
2024-02-16 17:42:52
前言
LeetCode 是一个流行的在线算法平台,提供多种算法和数据结构问题,供学习者和工程师解决。LeetCode #134 加油站问题是一个常见的动态规划问题,考察了在给定加油站和消耗燃料量的情况下,判断能否完成环形旅行的算法能力。
问题
假设你有 n 个加油站,分别在 [stations[0], stations[1], ..., stations[n-1]] 位置,每个加油站都有 gallons[i] 升汽油。同时,你有 m 个起点,分别在 [start[0], start[1], ..., start[m-1]] 位置。
你从某个起点出发,且汽车油箱里一开始有 capacity 升汽油。当你停留在某个加油站时,你可以把汽车油箱里的汽油全部补满,而不需要支付任何费用。
返回是否可以从某个起点出发,并经过一系列加油站,最终回到出发点,同时满足汽车油箱始终有汽油。
解决方案
我们可以使用动态规划的方法解决这个问题。令 dp[i] 表示从起点 start[i] 出发,是否可以到达下一个加油站 stations[i+1]。
初始化:
dp[0] = True # 从第一个起点出发,可以到达下一个加油站
for i in range(1, m):
dp[i] = False # 其他起点,初始时无法到达下一个加油站
动态规划:
for i in range(1, n):
for j in range(m):
if dp[j]:
if stations[i] - stations[j] <= capacity:
dp[j] = True # 从当前起点出发,可以到达下一个加油站
检查结果:
for i in range(m):
if dp[i]:
return True # 有至少一个起点可以到达所有加油站
如果最终 dp 数组中所有元素都为 False,则说明无法完成环形旅行。
代码实现(Swift)
func canCompleteCircuit(_ stations: [Int], _ gallons: [Int], _ capacity: Int) -> Int {
var dp = Array(repeating: false, count: stations.count)
dp[0] = true
for i in 1..<stations.count {
for j in 0..<stations.count {
if dp[j] && stations[i] - stations[j] <= capacity {
dp[j] = true
}
}
}
for i in 0..<stations.count {
if dp[i] {
return i
}
}
return -1
}
复杂度分析
- 时间复杂度:O(n^2),其中 n 是加油站的数量。
- 空间复杂度:O(n),存储动态规划表 dp。