zoukankan      html  css  js  c++  java
  • leetcode Gas Station

    gas[i]表示第i个站点可以加的油,cost[i]表示到下一个站点要消耗的油,一开始油箱空,假设油箱可以装无限的油。然后在一个环中。那个起点开始可以绕一圈回到原点,有且仅有一个答案。如果没有则返回-1.

    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.

    思路一,一开始很简单的想到就是遍历一下每个节点看看能不能走一圈就行。然后需要的剪枝是,如果该起点的cost比gas大,那就不用试了,肯定不行,还有就是如果gas-cost的累加和小于0了也是不要再继续试了。

    class Solution {
    public:
        int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
            vector<int> left(gas);
            for (int i = 0; i < left.size(); ++i)
                left[i] = cost[i] - gas[i];
            for (int i = 0; i < left.size(); ++i)
            {
                int sum = 0, cnt = 0;
                if (left[i] > 0)
                    for (int j = i; cnt < left.size(); ++j)
                    {
                        j = j % left.size();
                        sum += left[j];
                        if (sum < 0)
                            break;
                    }
                if (cnt == left.size())
                    return i;
                cnt = 0;
            }
            return -1;
        }
    };
    View Code

    每个节点都考虑必然超时啊。然后我们稍微改进一下就行了。

    我们用left数组存每个节点剩余的油,也就是gas[i]-cost[i],可能是负数,那么我们从0开始,如果left[i]的累加一直都大于等于0循环回到原点,那就是有解。如果累加到某个小标小于0了,那么我们不是从i+1继续判断累加值,而是从累加到的那个点的下一个点开始继续判断,因为之前的累加和已经不可能走完了,所有起点不会再前面。这样的话,我们要判断的是,一旦有绕过最后一个点又从头开始的时候,那么要么就找到了节点,要么就是没有符合的点,也就是终止条件之一了。例如我们的left数组为:

    -2, 2, -2, -1, 4, 6,

    然后6又循环到-2.

    那么我们一开始sum是-2,那么i+1判断2大于等于0,符合,然后2+ -2 等于0还是符合,然后-1不符合了,然后4符合,4+6=10符合,然后绕到-2,变成8还是大于等于零继续,加2变10,然后-2, -1 最后回到4的时候是大于零的。所以我们刚才从4开始就是符合回来的,那么4的下标就是要返回的答案。当然我的例子举得不是很对,因为不止一个答案,6开始也可以。但题目说只有一个答案的思路和上面说的是一样的。这样就只是O(n)的时间了。

    这是一开始试着写的比较挫的代码:

    class Solution {
    public:
        int canCompleteCircuit(vector<int> &gas, vector<int> &cost)
        {
            vector<int> left(gas);
            for (int i = 0; i < left.size(); ++i)
                left[i] = gas[i] - cost[i];
            for (int i = 0; i < left.size(); )
            {
                int sum = 0, cnt = -1, in = i;
                bool flag = false;
                while(sum >= 0)
                {
                    sum += left[in];
                    in++;
                    if (in >= left.size()) flag = true;
                    in = in % left.size();
                    cnt++;
                    if (cnt == left.size())
                        return i;
                }
                if (flag) return -1;
                i = in;
            }
            //return -1;
        }
    };
    View Code

    然后改的比较好看一点,变量少了一些如下:

    class Solution {
    public:
        int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
            vector<int> left(gas);
            for (int i = 0; i < left.size(); ++i)
                left[i] = cost[i] - gas[i];
            for (int i = 0; i < left.size(); ++i)
            {
                int sum = 0, cnt = 0;
                if (left[i] > 0)
                    for (int j = i; cnt < left.size(); ++j)
                    {
                        j = j % left.size();
                        sum += left[j];
                        if (sum < 0)
                            break;
                    }
                if (cnt == left.size())
                    return i;
                cnt = 0;
            }
            return -1;
        }
    };
  • 相关阅读:
    004 RequestMappingHandlerMapping
    003 HandlerMapping
    002 环境配置
    001 springmvc概述
    011 使用AOP操作注解
    010 连接点信息
    009 通知类型
    一台服务器的IIS绑定多个域名
    程序包需要 NuGet 客户端版本“2.12”或更高版本,但当前的 NuGet 版本为“2.8.50313.46”
    通过ping 主机名,或者主机名对应的IP地址
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4156646.html
Copyright © 2011-2022 走看看