welcome to my blog
LeetCode Top Interview Questions 134. Gas Station (Java版; Medium)
题目描述
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1).
You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1.
Note:
If there exists a solution, it is guaranteed to be unique.
Both input arrays are non-empty and have the same length.
Each element in the input arrays is a non-negative integer.
Example 1:
Input:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.
Example 2:
Input:
gas = [2,3,4]
cost = [3,4,3]
Output: -1
Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.
第一次做; 借助了不完整的数学证明, 比如能从a走到b-1, 但走不到b, 能推出注释中的三个式子; 最主要的一点没有证明: 如果gas[0,n-1]>=cost[0,n-1], 那么一定有解; 面试的时候推荐使用最自然的想法, 当然了, 这种方法也得会, 数学真是太关键了
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int start=0, left=0;
int global=0;
for(int i=0; i<n; i++){
global = global + (gas[i] - cost[i]);
left = left + (gas[i] - cost[i]);
if(left<0){
start = i+1;
left = 0;
}
}
return global >= 0 ? start : -1;
}
}
第一次做; 暴力解法: 从每一个位置开始, 看看能不能走回来, 这是最自然的思路, 但是很慢, 时间复杂度O(N^2);
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int gasSum=0, costSum=0;
for(int i=0; i<n; i++){
gasSum += gas[i];
costSum += cost[i];
}
if(gasSum < costSum)
return -1;
for(int i=0; i<n; i++){
int left = gas[i];
int cos = cost[i];
if(left>=cos){
int index = i;
int count = 0;
while(count<n){
index++;
index = index % n;
left = left - cos + gas[index];
cos = cost[index];
if(left<cos)
break;
count++;
}
if(count==n)
return i;
}
}
return -1;
}
}
力扣题解; 最优解, 借助数学证明
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int total_tank = 0;
int curr_tank = 0;
int starting_station = 0;
for (int i = 0; i < n; ++i) {
total_tank += gas[i] - cost[i];
curr_tank += gas[i] - cost[i];
if (curr_tank < 0) {
starting_station = i + 1;
curr_tank = 0;
}
}
return total_tank >= 0 ? starting_station : -1;
}
}