0
点赞
收藏
分享

微信扫一扫

[LeetCode]134. 加油站(java实现)贪心、双指针

杏花疏影1 2022-03-18 阅读 26

[LeetCode]134. 加油站(java实现)贪心、双指针

1. 题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 读题(需要重点注意的东西)

思路(贪心、双指针):
由于是走一圈,我们将加油站复制一遍放到原加油站数组后,起点start从第1个加油站遍历到第n个加油站,如果end - start + 1 == n,则说明能够走一圈。
在这里插入图片描述

  1. 首先用每个位置的 gas 减去 cost 求出当前位置的真正花费 sum,然后将 sum 数组扩展为 2n,使得sum[i + n] = sum[i]
  2. 定义两个指针 startend,分别表示当前的起点,和在这个起点下能走到的终点,tot 为当前油量,当在某一个节点sum < 0时,说明达到了终点
  3. 如果end - start + 1 == n,返回true
  4. 否则start++

时间复杂度为O(n2)

优化:
假设从当前start开始,end - start + 1 < n,那么从startend中的任何一个节点开始,都不可能有end - start + 1 == n,因此如果end - start + 1 < n,则直接将start = end + 1,从而将时间复杂度优化成O(n)

为什么?
在这里插入图片描述
start可以走到end,那么说明当汽车达到第k个节点的汽油量是大于或者等于0的(未加gas[k]),此时都不能行驶一圈。

那么如果当k是起始节点的时候,汽油量初始为0(未加gas[k]),就更不可能不能行驶一圈了。

3. 解法

---------------------------------------------------解法---------------------------------------------------

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        int[] sum = new int[2 * n];
        for(int i = 0;i < n * 2;i++)
            sum[i] = gas[i % n] - cost[i % n];

        int start = 0, end = 0, tot = 0;
        while(start < n && end <= 2 * n){
            tot += sum[end];
            // 如果当前汽油量小于0了
            while(tot < 0){
                tot = 0; // 更新start、tot
                start = end + 1; // 优化
            }
            if(end - start + 1 == n) return start;
            end++;
        }
        return -1;
    }
}

可能存在的问题:

4. 可能有帮助的前置习题

5. 所用到的数据结构与算法思想

6. 总结

举报

相关推荐

0 条评论