当前位置: 首页 > 知识库问答 >
问题:

算法 - Leetcode加油站问题,这个答案该怎么理解?

孙俊彦
2024-03-31

Leetcode加油站问题,这个答案该怎么理解?

题目地址

我在官方题解的下方评论中发现了一个答案,但是对于为什么这个答案可行我并不理解。

为什么sum >= 0说明有解,否则就无解呢?

这个答案我有一些思路。

remainGas[i] = gas[i] - stataion[i]sum = all remainGas[i] i from 0 to n -1
  • sum >= 0

    • 将相邻的remainGas[i],且它们的前缀和(这里的前缀和指的是这几个remainGas构成序列的前缀和)都大于等于0,合并成一个节点(此时这个节点代表了一段路径)。
    • 这样我们就可以得到一个更小的子问题了,而且我们总是可以合并的,因为sum>=0(如果不存在的话,sum应该是<0的。)。
    • 最终只会得到一个节点(此时这个节点代表了一条可行的路径)

任何一种可行解都可以按照上述的方法构造出来。(这个很容易构造,可行解的前缀和都是>=0的,从前往后合并就可以了)

  • sum < 0
    假设此时存在一个可行解,那么存在一个上述的构造过程。由构造过程可得,sum应该是>=0(每次合并时前缀和都是>=0的,最后一次也还是),矛盾。故不存在可行解。

为什么起点是 (minIndex + 1 )%gas.length呢?

评论区答案

class Solution {    public int canCompleteCircuit(int[] gas, int[] cost) {        int sum = 0;        int min = Integer.MAX_VALUE;        int minIndex = -1;        for(int i = 0; i < gas.length; i++){            sum = sum + gas[i] - cost[i];            if(sum < min && sum < 0){                min = sum;                minIndex = i;            }        }        if(sum < 0) return -1;        return (minIndex + 1 )%gas.length;    }} 

我在评论区还看到另一份思路一样的答案,并且他还给出了一些说明。

没有直接前缀和的吗? 显然如果存在仅一个起点S能走完全程,那么从任意一个点出发绕完一圈,在S处的油量一定是最少的。 所以只要验证走完全程的前缀和非负,然后找到前缀和最小的点就是起点了
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {        // 化为边上的净开销        int size = gas.size();        int i;        vector<int> edge_cost(size);        for (i = 0; i < size; i++) edge_cost[i] = gas[i] - cost[i];        int cs = 0;        for (i = 0; i < size; i++) {            int tmp = edge_cost[i];            edge_cost[i] = cs;            cs += tmp;        }        if (cs < 0)return-1;        int p = 0;        cs = 0;        for (i = 0; i < size; i++) {            if (edge_cost[i] < cs) {                cs = edge_cost[i];                p = i;            }        }        return p;    }

这里的显然我也没有明白。

共有1个答案

芮意
2024-03-31

为什么起点是 (minIndex + 1 )%gas.length呢?

remainGas[0] ... remainGas[i] ... remainGas[n-1]

假设i为起点位置,那么sum remainGas[i...j](j = i, (i+1)%n .. (i+n-1)%n) > 0(必须保证任意的前缀都>0才可以走到下一站),所以
sum remainGas[0..i-1] < sum remainGas[0...j] (j = i, ..., n-1)

假设存在z,距离i最近且使得sum remainGas[0...z] < sum remainGas[0..i-1],那么
sum remainGas[z...j](j = z, .. i-1) > 0,此时从以z+1为起始点,我们走到i是可行的,又因为i为起始点,所以以z+1为起点可以走完一圈。此时就存在了两个解,与题目中说的存在唯一解矛盾,故不存在这样的z

sum remmainGas[0...i-1]为min(sum remaiGas[0..j]) (j = 0,1,...n-1)

 类似资料:
  • 我想用真值表找到区域。 图形pic 但是,我有些怀疑。 如何计算x>2是否? 如何计算x>2是否是? 如何使用此真值表查找区域? 我想使用if语句打印,如下所示 Java这个真值表怎么算?

  • leetcode糖果问题,这种做法为什么可行? leetcode糖果问题 这个官方题解并没有证明,只是说了一下过程。我有以下几点疑问: left[..]是在仅符合左规则下分的糖果最少的分配方案吗?同样的right[...]是在仅符合右规则下分的糖果最少的分配方案吗? 为什么取仅符合左规则的值和仅符合右规则的值的最大值可以同时符合左右规则呢? 就算符合左右规则,为什么这种方案下分的糖果是最少的呢?

  • Q. 聊聊你作品中有关交互设计的亮点是什么? 通常对于没有实习经验的同学而言,他可能不知道如何回答才算是交互设计的亮点,觉得交互设计的就是画线框图,其实不然。需求分析、用户分析、需求转化、界面布局、信息架构和操作流程等都是交互设计的一部分。可以表达自己将需求转化为设计解决方案的独特处,界面元素布局等细节的优化、以及设计方案使得信息架构层级更清晰或缩短了用户完成任务的流程等。最好可以通过用户测试、用

  • Q. 聊聊你作品中有关交互设计的亮点是什么? 通常对于没有实习经验的同学而言,他可能不知道如何回答才算是交互设计的亮点,觉得交互设计的就是画线框图,其实不然。需求分析、用户分析、需求转化、界面布局、信息架构和操作流程等都是交互设计的一部分。可以表达自己将需求转化为设计解决方案的独特处,界面元素布局等细节的优化、以及设计方案使得信息架构层级更清晰或缩短了用户完成任务的流程等。最好可以通过用户测试、用

  • 有一个由 n x n 个格子组成的正方形,除了其中一个格子是空外,其余格子都放置了一个数字,数字从 1 到 n x n - 1,然后通过移动数字,让数字从左到右从上到下按顺序排列,空的格子会在右下角。 求实现目标的最小步骤数,并列出所有步骤。一个步骤中在一个方向上可以移动多个数字,步骤格式使用 [空格子位置, 移动方向, 移动数字个数] 表示 移动方向有 rtl, ltr, ttb, btt 四种

  • 这是一个骇人听闻的问题:爱丽丝是一个幼儿园老师。她想给班上的孩子们一些糖果。所有的孩子坐成一行(他们的位置是固定的),每个人根据他(她)在班上的表现有一个评级分数。爱丽丝想给每个孩子至少一颗糖。如果两个孩子挨着坐,那么评分较高的那一个必须得到更多的糖果。爱丽丝想省钱,所以她需要尽量减少给孩子们的糖果总数。 测试数组:n=10,n个元素为[2 4 2 6 1 7 8 9 2 1]。我得到的答案是18