1.题目描述:
在一条环路上有n个加油站,其中第i个加油站有汽油gas[i]升。你有一辆油箱容量无限的的汽车,从第i个加油站开往第i+1个加油站需要消耗汽油cost[i]升。你从其中的一个加油站出发,开始时油箱为空。给定两个整数数组gas和cost,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回-1。如果存在解,则保证它是唯一的。
2.暴力解法:
从每个加油站开始走,用while循环模拟环形遍历,自己写的代码:
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
for (int i = 0; i < gas.length; i++) {
int sum = 0;
int j = i;
int num = 0;
boolean flag = false;
while (num < gas.length) {
sum += gas[j];
if (cost[j] > sum) {
flag = true;
break;
}
else sum -= cost[j];
j++;
j %= gas.length;
num++;
}
if (!flag) return i;
}
return -1;
}
}
优化的暴力解法:还是超时
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
for (int i = 0; i < gas.length; i++) {
int rest = gas[i] - cost[i];
int j = (i + 1) % gas.length;
boolean flag = false;
while (rest > 0 && j != i) {
rest += gas[j] - cost[j];
j = (j + 1) % gas.length;
}
if (j == i && rest >= 0) return i;
}
return -1;
}
}
3.贪心算法:
首先总油量大于总消耗量,必有解。统计每一个加油站的rest[i] = gas[i] - cost[i],从某一个加油站开始,如果本身小于0或者累计之后出现小于0,那么很容易想到出发点不能是前面的任何一点(举例可以想一下),出发点往后推,rest重新开始计。
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int index = 0;
int rest = 0;
int sumRest = 0;
for (int i = 0; i < gas.length; i++) {
rest += gas[i] - cost[i];
sumRest += gas[i] - cost[i];
if (rest < 0) {
rest = 0;
index = (i + 1) % gas.length;
}
}
if (sumRest < 0) return -1;
else return index;
}
}