方法一,自己想的,超时
双重循环
从第一个点开始循环尝试,
如果最终能走到终点,说明可行。
public int canCompleteCircuit(int[] gas, int[] cost) {
int res = -1;
int n = gas.length;
int remainGas;
int j;
for (int i = 0; i < n; i++) {
remainGas = 0;
for (j = i; j < n + i; j++) {
int tmp = j;
if (tmp >= n) {
tmp = tmp - n;
}
remainGas += gas[tmp] - cost[tmp];
if (remainGas < 0) {
break;
}
}
if (j == n + i) {
res = i;
break;
}
}
return res;
}
方法二,官方题解
利用结论:
假设x到不了y+1,那么[x,y]中的任意一个节点都无法到达y+1。那么循环直接从y+1开始即可
改造我们的代码
public int canCompleteCircuit(int[] gas, int[] cost) {
int res = -1;
int n = gas.length;
int remainGas;
int cnt = 0;
int tmp = 0;
for (int i = 0; i < n; i++) {
remainGas = 0;
for (cnt = 0; cnt < n; cnt++) {
tmp = (i + cnt)%n;
remainGas += gas[tmp] - cost[tmp];
if (remainGas < 0) {
break;
}
}
if (cnt == n) {
res = i;
break;
}else {
i = i + cnt;
}
}
return res;
}
评论区做法
利用唯一解的特性;
使用一次遍历,如果存在解,那么解一定出现在最耗油的一段路之后。
public int canCompleteCircuit3(int[] gas, int[] cost) {
int res = -1;
int n = gas.length;
int remainGas = 0;
int minRemain = Integer.MAX_VALUE;
int use = 0;
for (int i = 0; i < n; i++) {
use = gas[i] - cost[i];
remainGas += use;
if (remainGas < minRemain) {
minRemain = remainGas;
res = i;
}
}
if(remainGas >= 0){
return (res + 1)%n;
}else {
return -1;
}
}