【LeetCode每日一题】[中等]134. 加油站
134. 加油站
算法思想:数组
题目:
java代码–暴力
暴力,枚举每一个位置,判断能都行驶一周
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
//暴力,枚举每一个位置,判断能都行驶一周
int n = gas.length;
for (int i = 0; i < n; i++) {
//遍历每一个位置
int oilMass = 0;
int j = i;
while (oilMass >= 0) {
//判断当前位置能否行驶一周
oilMass = oilMass + gas[j] - cost[j];
j = (j + 1) % n;
if (oilMass >= 0 && j == i) {
//如果可以则返回i
return i;
}
}
}
return -1;//不能行驶一周
}
}
java代码–遍历一遍
利用,x 能到 y 以及 y 之前的任何一站,但是无法到达 y 的下一站,则 [x,y] 区间内的任意一站无法到达y的下一站;
解释说明:
- 假设存在x’ 是 [x,y] 站中一站;
- x 能到达 x 至 y 中的每一站,则一定 [x, x’] 叠加和以及 [x, y] 叠加和 >=0,
- x 不能到 y 下一站,则在 [x,y+1] 叠加和 < 0 ;
- 其中可知 [x,y+1] - [x, x’] = [x’, y+1] < 0;
- 所以, [x,y] 区间内的任意一站无法到达y的下一站;(遍历的时候可以将x直接跳到y+1,中间的站不用考虑)
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
//遍历一遍,O(n)
//利用,x不能到y的下一站,则[x,y]区间内的任意一站无法到达y的下一站
int n = gas.length;
int i = 0;
while (i < n) {
int oilMass = 0;
int j = i;
int count = 0;//用来计数,是否行驶了一周
//寻找 i 最大能到达的站 y
while (oilMass >= 0 && count < n) {
//判断当前位置能否行驶一周
oilMass = oilMass + gas[j] - cost[j];
j = (j + 1) % n;
count++;
if (oilMass >= 0 && count == n) {
//如果行驶了一周,返回i
return i;
}
}
i = i + count;//如果不能行驶一周,i 直接移动到 y 的下一站
}
return -1;//不能行驶一周
}
}
java代码
利用,如下图,分析来源
代码主要功能:寻找图中黑线的最低点;如果总和>=0,则起始点是最低点的下一个位置;如果总和<0则不可能存在方案
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int totalGas = 0;//总和
int minGas = Integer.MAX_VALUE;
int mindx = 0;
for (int i = 0; i < n; i++) {
totalGas += gas[i] - cost[i];
if (totalGas < minGas) {
//寻找最低点,记录下标
minGas = totalGas;
mindx = i;
}
}
return totalGas >= 0 ? (mindx + 1) % n : -1;
}
}