134. Gas Station

一、题目

  1、审题

  2、分析

    给出一个数组 gas,代表汽车在此地点可以加油 gas[i];一个数组 cost,代表汽车从此地点到达下一个地点需要耗费的油量 cost[i],设汽车油箱容量无限,求汽车顺时针能绕一圈的起始地点的下标。

二、解答

  1、思路: 

    方法一、

      运用两层循环。

      第一层循环代表汽车的起始地点下标;

      第二层循环判断汽车能否绕行一圈。

    public int canCompleteCircuit(int[] gas, int[] cost) {
     
        int cur = 0;
        int len = gas.length;
        while(cur < len) {
            int tmp = cur;
            int gasTotal = 0;
            boolean flag = true; // 第一次进循环
            while(tmp != cur || flag) {
                // 先加油、再耗油
                gasTotal += gas[tmp] - cost[tmp];
                if(gasTotal < 0)
                    break;
                tmp++;
                tmp = tmp % len;
                flag = false;
            }
            
            if(gasTotal >= 0)
                return cur;
            
            cur++;
        }
        return -1;
    }

  方法二、

    有如下规律:

    ①、如果所有的 gas 之和 大于等于 cost 之和,则必定存在一条能循环绕一周的路径。

    ②、若从 A 出发不能到达 B,且 A 与 B 之间的地点均不可到达 B,则 A 与 B之间的地点均不能作为起始点。

    public int canCompleteCircuit3(int[] gas, int[] cost) {
        //determine if we have a solution
        int total = 0;
        for (int i = 0; i < gas.length; i++) {
            total += gas[i] - cost[i];
        }
        if (total < 0) {
            return -1;
        }
        
     // find out where to start
        int tank = 0;
        int start = 0;
        for (int i = 0; i < gas.length;i++) {
            tank += gas[i] - cost[i];
            if (tank < 0) {
                start = i + 1;
                tank = 0;
            }
        }
        return start;
    }

   方法三、

     采用两个指针,start 从下标 0 开始, end 从下标 len - 1 开始。变量 sum 初始为 gas[end] - cost[end],即假使起始点为 end。

       若 sum > 0, 则start 向后移动,且 sum 动态改变;

     若 sum < 0,则 end 向前移动,且 sum 进行改变。

     当 start >= end 时跳出循环,若 sum >= 0,即总的 gas >= cost,返回 end,否则 返回 -1,即不可达。

    public int canCompleteCircuit4(int[] gas, int[] cost) {
        
        int end = gas.length - 1;
        int start = 0;
        int sum = gas[end] - cost[end];
        
        while(start < end) {
            if(sum >= 0) {
                sum += gas[start] - cost[start];
                ++start;
            }
            else {
                --end;
                sum += gas[end] - cost[end];
            }
        }
        return sum >= 0 ? end : -1;
    }
原文地址:https://www.cnblogs.com/skillking/p/9760975.html