LeetCode Array 134 Gas Station

134. Gas Station

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.

solution 1:Brute Force

首先确定可能起始点位置,然后检验是否可以绕一圈

public class GasStation {
    /*
    example:
    gas  = 1, 2, 3, 4, 5
    cost = 3 ,4 ,5 ,1, 2
    起始点的条件是 gas[i] >= cost[i]
     */
    public int canCompleteCircuit(int[] gas, int[] cost) {
        if (gas == null || cost == null || gas.length==0||cost.length==0) 
        	return -1;
        for (int i = 0; i < gas.length; i++) {
            if (gas[i] < cost[i]) continue;
            int j = (i+1)%(gas.length);
            int gas_s = gas[i]-cost[i];
            int flag = 1;
            while (j % (gas.length)!=i) {
                gas_s = gas_s + gas[j % (gas.length)] - cost[j % (gas.length)];
                j++;
                if (gas_s<0) {
                    flag = 0;
                    break;
                }
            }
            if (flag == 1) {
                return i;
            }
        }
        return -1;
    }
}

solution 2:

利用一个数学定理:
如果一个数组的总和非负,那么一定可以找到一个起始位置,从他开始绕数组一圈,累加和一直都是非负的
因此此问题转化为首先判断是否gas数组元素的和大于等于cost数组,大于等于的情况下,确定起始点位置,小于的情况下不可能有解,返回-1
对于找到起始位置,可以遍历数组,假设从 i 开始前进,到达 j 的时候没油了,那么我们下一步不应该从 i+1 开始遍历,而是应该直接从 j+1 开始遍历。
因为如果i到j的剩余油量小于0,而i显然油量大于0,那么从 i+1 到j就必定更小,同理,i+2 , i+3 也不用考虑,所以就应该直接从 j+1 开始继续遍历,并保存之前欠缺的油量总和。

	public int canCompleteCircuit(int[] gas, int[] cost) {
	    if (gas == null || cost == null || gas.length==0||cost.length==0) 
	    	return -1;
	    int tank = 0, total = 0, start = 0;
	    for (int i = 0; i< gas.length; i++) {
	        tank += gas[i]-cost[i];
	        // total为gas[i] - cost[i]的总和,tank记录剩余燃料,如果tank = 0,
	        // 说明之前确定的start是错误的,
	        // 需要从j开始继续遍历,把start设置为j+1
	        if (tank < 0) {
	            total += tank;
	            tank = 0;
	            start = i+1;
	        }
	    }
	    total = total + tank;
	    return (total >= 0)? start:-1;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值