LeetCode134 加油站(贪心)
程序员文章站
2024-03-11 11:28:25
...
题目链接:leetcode
题面
题目大意
gas表示到达 i 位置后能得到的充值
cost表示从 i 离开后需要的消费
问是否能够从前往后绕一圈回到原点
解题思路
易错点
对于一个起点,即使途中所有的充值和消费大于等于0,但是途中某个位置一旦没油了就会终止。
枚举
枚举所有起点,暴力检查。
时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1)。
贪心
容易想到能绕一圈的前提是所有的所有点的充值和消费求和要大于等于0,在此前提我们去找起点。对于一个合法的起点,我们应该尽可能地时前半段地充值和消费抵消后剩余的油量来到最大,这样就不会发生中途没油的错误。根据容斥定理,前半段剩余油量最大等价于后半段油量最少。
枚举起点,当且仅当 prefix_sum(i-1) 达到最少时,i 为起点。
证明
反证法,传送门
代码实现
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int sum=0, _min = ~(1<<31), id=0;
for (int i=0; i<gas.size(); i++) {
sum += gas[i]-cost[i];
if (sum < _min) {
_min = sum;
id = (i+1)%gas.size();
}
}
return sum<0?-1:id;
}
};