在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
package com.leetcode.july;
/**
* @author jiayoo
* 2018 / 7 /23
* 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
如果题目有解,该答案即为唯一答案。
输入数组均为非空数组,且长度相同。
输入数组中的元素均为非负数。
* https://leetcode-cn.com/problems/gas-station/description/
* 分类 : 贪心算法。
* 难度: 中等
*
*/
public class Demo4 {
public static void main(String[] args) {
Demo4 d4 = new Demo4();
int[] g1 = {1,2,3,4,5};
int[] c1 = {3,4,5,1,2};
int[] g2 = {2,3,4};
int[] c2 = {3,4,3};
System.out.println(d4.canCompleteCircuit(g1, c1));
System.out.println(d4.canCompleteCircuit(g2, c2));
}
/**
* @param gas
* @param cost
* 这个算法比下面一个算法复杂度高。
* 但应该更好理解一点。
*
* @return
*/
public int canCompleteCircuit(int[] gas, int[] cost) {
int i, j, len1, k;
len1 = gas.length;
int[] arr = new int[len1];
for (i = 0; i < len1; i++) {
arr[i] = gas[i] - cost[i];
}
int count = 0; // 记录当前已经走过的加油站的数量
int max = 0; // 记录当前油量
k = 0; // 这里记录的是偏移量
/*
* 第一个for 保证每一个加油站都被计算到
* 第二个for 用于判断每一加油站 是否 符合题目要求
* k 用来 计算偏移量 使 第二个for 确实是按 顺序 进行行走的 即实现了循环
* 1. max 用来记录 当前油量 如果小于零 显然无法继续前行 换下一个
* 2. 不小于零的情况 使 计数count ++, 并且 让 偏移量k 加1
* 3. 跳出第二个for 以后 则 判断 这个加油站是否符合要求
* 4. 最后 如果遍历完所有加油站后依旧没找到 则 返回-1
* */
for(i = 0; i < len1; i++) {
k = i;
for (j = 0; j < len1; j++) {
if (k >= len1) {
max += arr[k-len1];
}else {
max += arr[k];
}
if(max < 0) {
max = 0;
break;
}
k++;
count++;
}
if (count >= len1 ) {
return i;
}
count = 0;
}
return -1;
}
/**
* @param gas 得到
* @param cost 花费
*
* 这个算法显然比上面的那个要好 , 但是一开始并没有想到
* sum 可以看作是 判断 当前位置是否真的可以走通 小于 0 表示当前位置走不通
* total 表示 判断 整个 数组是否走的通 只有 total 大于零 才走的通 这点很重要
* 用一个for 就行了 很取巧
* 1.首先 看最后 total 只有大于等于零 才返回 index, 这样就保证了 index 确实 是存在
* 2. 在for循环里 通过 sum 判断 当前 位置 一直到结束都没有出错 , 并且 不管 index 位于何处 都能判断
* 它前面 的 位置 是错误的, 整条路又走的通, 因此 起点位置就是当前位置。
*
* @return 返回可以走的路径
*/
public int canCompleteCircuit1(int[] gas, int[] cost) {
if(gas==null||gas.length==0||cost==null||cost.length==0||gas.length!=cost.length){
return -1;
}
int sum=0;
int total=0;
int index=0;
for(int i=0;i<gas.length;i++){
sum+=gas[i]-cost[i];
total+=gas[i]-cost[i];
if(sum<0){
index=i+1;
sum=0;
}
}
if(total<0){
return -1;
}
return index;
}
}