871. 最低加油次数
2024-10-08 16:51:33
Problem: 871. 最低加油次数
1.动态规划
思路
起初看到题目的规模不大,便以为可以使用$O(n^2)$的算法来做,这是想到用动态规划的一个契机。
再就是题目是符合动态规划的条件的:
- 题目符合无后效性,后面的加油站的选择对前面没有影响。
- 题目存在最优子结构,即我们可以通过构造
dp[i][j]
,其中i
表示到达第i
站,加了j
次油时所剩的油,通过不断扩大i
的规模即可求解。
起初,设定dp[0][0]
为startFuel - stations[0][0]
,表示到达第0
站而且未加油,如果这个值大于0
,则可以加上stations[0][1]
。
之后我们遍历i
,并从大到小遍历所有小于等于i
的j
,判断dp[i-1][j]
能否到达第i
站,如果可以,而且这样剩的油更多的话,则更新dp[i][j + 1]
。这里注意到,由于dp[i]
之和前dp[i - 1]
有关,我们可以省略这一维度。而我们从大到小遍历j
,可以防止在更新过程中用dp[i][j + 1]
的值覆盖之前dp[i - 1][j + 1]
的值。
最后在遍历结束后,我们找出最小的所剩油量足够行驶完剩余距离的次数即可。
复杂度
- 时间复杂度: $O(n^2)$:双层for循环,
n
为数组长度。 - 空间复杂度: $O(n)$:动态规划所用空间。
Code
1 | class Solution { |
2.贪心
思路
本题实际上有更好的做法。要知道,能够使用动态规划解决的题目就有可能能用贪心解决。
想象这样一个情景,车在行驶的过程中,如果身上的油足够它走过接下来若干个加油站,那么它如果要加油次数最少,肯定要在这些加油站中选一个能加最多油的站先加上。
这样做的情况下加油次数最少是保证了,但是能否确保不会因为少加油而无法到达终点?
这是可能存在的,但是实际上由于要到达终点我们会经过所有的加油站,如果后面发现油不够了,只要还记住没有加油的站里哪个油最多,一一再加上也是可以的(反悔)。
上面我们发现,我们需要维护的是已经到达的站按油量最多排序的优先队列,再加上贪心即可解决问题。
复杂度
- 时间复杂度: $O(n)$:
n
为数组长度。 - 空间复杂度: $O(n)$:最大堆所用空间。
Code
1 | class Solution { |