class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
# # 先计算一下这一站加的油 - 到达下一站消耗的油 的差值
# # 即diff = gas - cost = [-2, -2, -2, 3, 3]
# # [-2, -2, -2, 3, 3]
# temp = [a-b for a, b in zip(gas, cost)]
# # 法1 暴力法 解法1
# temp = temp + temp[:-1]
# for i in range(len(gas)):
# temp_sum = 0
# flag = 0
# for j in range(i, i+len(gas)):
# temp_sum += temp[j]
# if temp_sum < 0:
# flag = 1
# break
# if flag == 0:
# return i
# return -1
# 暴力求解解法2
# # 先计算一下这一站加的油 - 到达下一站消耗的油 的差值
# # 即diff = gas - cost = [-2, -2, -2, 3, 3]
# total = 0
# diff = [a - b for a, b in zip(gas, cost)]
# diff_cycle = diff + diff
# diff_cycle = [-2, -2, -2, 3, 3, -2, -2, -2, 3, 3]
# n = len(gas)
# if sum(gas) < sum(cost):
# return -1
# for i in range(n):
# # 如果diff[i]< 0说明这个站不能作为起点
# if diff[i] < 0:
# continue
# for j in range(n):
# total += diff_cycle[i+j]
# if total < 0:# 只要total<0说明油箱没油了,不足以支持到下一站
# total = 0 # 下一个站点total要重新定义
# break
# if j == n-1: # 如果j == n-1,说明可以绕一圈到原站点
# return i
# return -1
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
# 贪心算法写法1
# 这个贪心算法,我完全没看懂,我有一个关键的问题,那就是为什么它不会错过真正的起始点呢?
# 当total < 0时,我们将start设置为i+1,并重置total为0。这意味着我们认为从i+1到k之间的任何一个点都不可能是起始点。
# 但这是为什么呢?帮我解释一下吧。
# 假设存在一个有效的起始点 k,其中 start <= k <= i。
# 由于 total 在 i 时为负数:
# 从 start 到 i 的累积油量为负,意味着从 start 出发无法到达 i + 1。
# 如果 k 是 start 到 i 之间的某个点,那么从 k 出发,到达 i + 1 时,同样会因为 start 到 i 的累积油量为负而失败。
# ???这个点完全无法理解啊。
# 我懂了,这是因为在start到k的时候,油量是正的,而从k到了i+1就变负了,
# 如果从k出发,那结果只会更差,所以在start到i+1之间肯定是没有真正的起点的。
if sum(gas) < sum(cost):
return -1
total = 0
start = 0
for i in range(len(gas)):
total += gas[i] - cost[i]
if total < 0:
total = 0
start = i + 1
return start
# 贪心算法写法2
# if sum(gas) < sum(cost):
return -1
# diff = [a-b for a,b in zip(gas, cost)] # diff = gas - cost = [-2, -2, -2, 3, 3]
# total = 0 # 表示从起始站到当前站的油箱剩余
# start = 0
# for i in range(len(gas)):
# total += diff[i] # 如果这个 < 0说明当前油箱的剩余量 + (i站的油 - 到达i+1站的cost) < 0
# if total < 0:
# total = 0
# start = i+1
# return start
# total = 3 + 3 = 6 然后就结束了,就可以判断start = 3是其中一个解
# 贪心算法就是找到一个解就停止好了
# 总和>= 0 ,pre_sum + post_sum >= 0, 而post_sum >=0,则说明|post_sum| >= |pre_sum|