• [LeetCode] 134. 加油站


    最暴力的办法是需要枚举每一个起点,然后判断从该起点出发能否满足题意。
    从暴力算法出发,如何优化呢?

    1. 可以不需要枚举每一个起点吗?
      不可以,每一个起点的枚举肯定是少不了的
    2. 枚举每一个起点后,判断可能性时可以优化吗
      可能很快能想到前缀和,能做到O(1)下判断从该点出发后,到最后一个加油站时剩余油量。但是剩余油量>=0就代表满足题意了吗?不是的,很容易就想到反例。

    实际上,两层循环是少不了的。但是我们可以进行剪枝:

    1. 找到第一个符合题意的答案就直接输出
    2. 当油不够时可以直接退出内循环。

    实际上,经过一些数学推导,最终的时间复杂度是能做到O(n)的,因为前面不符合题意的起始点都不会跑完2层循环

    class Solution {
        public int canCompleteCircuit(int[] gas, int[] cost) {
            int n = gas.length;
            if (n == 0) return -1;
    
            int[] f = new int[n];
            for (int i=0;i<n;i++) {
                f[i] = gas[i] - cost[i];
            }
    
            int[] sum = new int[n];
            sum[0] = f[0];
            for (int i=1;i<n;i++) {
                sum[i] = sum[i-1] + f[i];
            }
    
            if (sum[n-1] < 0) return -1;
    
            for (int i = 0;i<n;i++) {
                if (f[i] >= 0) {
                    int tmp = 0;
                    int k = 0;
                    for (k = 0;k<n;k++) {
                        tmp+=f[(i+k)%n];
                        if (tmp < 0) break;
                    }
                    if (k==n) return i;
                }
            }
            return -1;
        }
    }
    
  • 相关阅读:
    最长上升序列,首尾连接
    带权并查集&&并查集
    开发者的小天地-1
    Binary Tree Maximum Path Sum
    Linked List Cycle II
    动归熟手题单
    java 正则表达式-忽略大小写与多行匹配
    KO之tab栏切换
    Vue中通过属性绑定为元素绑定style
    Vue中通过属性绑定为元素设置class
  • 原文地址:https://www.cnblogs.com/acbingo/p/14856892.html
Copyright © 2020-2023  润新知