一篇让我差点emo的力扣题目《1575.统计所有可行路径》

252 阅读3分钟

一、题目翻译

给定一个城市集合(locations),locations用数组表示。同时又给你 当前城市索引(start)目的地城市索引(finish)你初始拥有的汽油总量(fuel)。请你返回 在不超过油量的情况下,从 startfinish 所有可能的路径数目。

题目限制如下:

  • 城市locations[i]移动到城市locations[j]消耗的油量为:| locations[i] - locations[j] |
  • 油量fuel任意时刻都不能为负
  • 城市locations里的元素都是唯一且不重复的
  • 由于答案可能很大,请将结果对10^9+7取余后返回

二、示例

lc-1.png

lc-3.png

三、解题思路

其实我在做这道题的时候,我连题目都没读懂,这个是真事,后来是咋读懂的呢?把心静下来,硬着头皮一遍一遍的读,一遍一遍的理解,一遍一遍的做,但是并没有卵用。后来就对算法的训练停了2个星期。隔了2周再回过来做这题,忽然有一种 柳暗花明又一村 感觉,之前的疑惑也就都消失了。

有的时候可能就是这样,每个人的顿悟都不一样,时间不同,理解力不同,经历的也不一样。所以没什么可焦虑的,生活远不止这一个点,我们可以绕道而行,杀他个回马枪。

扯的有点远了,我们回归一下题目,做这道题的时候,如果没有思路的小伙伴,我能大致猜到你们在想什么:遍历,而且没有多余想法。就是2个字 遍历,怎么遍历我不知道,但是我知道肯定会用到遍历。

我们应该转变一下思路,从start到finish的方式无外乎2种,一种是直接到达,一种是间接到达(先到达另一个城市,再从另一个城市里中转到达finish)。

那么下面等式根据题意的话,就会恒成立:

dp[start][fuel] = dp[start][fuel] + dp[tempCity][fuel - tempFuel];

其中,dp[start][fuel]代表花费fuel油量的情况下,从start到达finish的路径数量。

右侧的dp[tempCity][fuel - tempFuel]代表从start到达中转城市tempCity(假设此时已经消耗了tempFuel油量)后,在剩余油量fuel - tempFuel的情况下,中转城市tempCity到达finish的路径数量。

这里解释一下为啥dp[start][fuel]出现了2次,这是因为我们对二维数组的定义就是在满足当前fuel的情况下,从start到达finish的总路径数,这是一个累加的操作,所以会出现2次。

function cacheRoutes(locations, start, end, fuel){
    let dp = new Array(start).fill(1).map( item => new Array(fuel+1).fill(0) );
    dp[end] = new Array(fuel+1).fill(1);
    let mod = 1000000007;
    
    for (let initFuel = 0; initFuel <= fuel; initFuel++){
        // 遍历油量
        for (let curCityIndex = 0; curCityIndex < locations.length; curCityInedx++){
            // 遍历当前的城市
            for (let restCityIndex = 0; restCityIndex < locations.length; restCityIndex++){
                // 遍历其他城市
                if (curCityIndex !== restCityIndex){ // 在这里会继承 “直接到达” 与 “间接到达”
                    // 当restCityIndex === finish时,此时求的就是“直接到达”,其余情况都是“间接到达”
                    let curToRestNeedFuel = Math.abs( locations[curCityIndex] - locations[restCityIndex] );
                    if (initFuel >= curToRestNeedFuel){
                        dp[curCityIndex][initFuel] += dp[restCityIndex][initFuel - curToRestNeedFuel];
                        dp[curCityIndex][initFuel] %= mod;
                    }
                }
            }
        }
    }
    return dp[start][fuel];
}

最后

以上就是我在写题解的心路历程,这篇文章同样收录在我的其中一个刚成立且不火的专栏里,感兴趣的小伙伴可以到我的主页里去寻找,我不敢说看到就是赚到,但是希望我写的能对你有启发,那么我们下篇再见。