Gas Station 加油站问题 @LeetCode

两种解法,暴力必须优化才能通过,DP直接通过。传说中的BloomBerg面试题?


package Level4;

import java.util.Arrays;

/**
 * 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, otherwise return -1.
 * 
 * Note: The solution is guaranteed to be unique.
 */
public class S137 {

	public static void main(String[] args) {
		int[] gas = {2,4};
		int[] cost = {3,4};
		System.out.println(canCompleteCircuit(gas, cost));
	}
	
	// O(n^2) 暴力
	public static int canCompleteCircuit(int[] gas, int[] cost) {
		int[] remain = new int[gas.length];
		for(int i=0; i<gas.length; i++){			// 优化1
			remain[i] = gas[i] - cost[i];
		}
		System.out.println(Arrays.toString(remain));
		
		for(int i=0; i<gas.length; i++){
			int capacity = 0;
			int j = i;
			boolean canComplete = true;
			do{
//				capacity += gas[j];
//				capacity -= cost[j];
				capacity += remain[j];
				if(capacity < 0){
					canComplete = false;
					break;
				}
//				j = (j+1) % gas.length;
				j++;						// 优化2,如果用mod运算就会TLE
				if(j == gas.length){
					j = 0;
				}
			}while(j != i);
			
			if(canComplete){
				return i;
			}
		}
		return -1;
	}
	
	// O(n) DP
	public static int canCompleteCircuit2(int[] gas, int[] cost) {
		int curSum = 0;			// 用于记录当前gas剩余量
		int total = 0;				// 记录走完一圈的gas剩余量
		int startIndex = 0;		// 记录能走完一圈的开始位置
		
		for(int i=0; i<gas.length; i++){
			int curRemain = gas[i]-cost[i];  
			if(curSum >= 0){		// 如果当前还有剩余量,继续
				curSum += curRemain;
			}else{					// 否则,从这里重新开始
				curSum = curRemain;
				startIndex = i;
			}
			total += curRemain;
		}
		
		return total>=0 ? startIndex : -1;
	}
}



public class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int len = gas.length;
        for(int i=0; i<len; i++) {
            int cap = gas[i];
            int cur = i;
            boolean ok = true;
            do{
                int next = (cur+1) % len;
                cap -= cost[cur];
                if(cap < 0) {
                    ok = false;
                    break;
                }
                cap += gas[next];
                cur = (cur+1) % len;
            } while(cur != i);
            if(ok) {
                return i;
            }
        }
        return -1;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值