leetcode 787. K 站中转内最便宜的航班 js题解

      //787. K 站中转内最便宜的航班
      var findCheapestPrice = function (n, flights, src, dst, K) {
        //把出和入存到map
        //key为dst,value为[src, cost]
        const innerMap = new Map();

        //key为src,value为[dst,cost]
        const outerMap = new Map();
        flights.forEach((item) => {
          const [src, dst, cost] = item;
          if (!innerMap.has(dst)) {
            innerMap.set(dst, [[src, cost]]);
          } else {
            innerMap.get(dst).push([src, cost]);
          }
          if (K !== 0) {
            if (!outerMap.has(src)) {
              outerMap.set(src, [[dst, cost]]);
            } else {
              outerMap.get(src).push([dst, cost]);
            }
          }
        });

        let minCost = -1;
        if (innerMap.has(dst)) {
          innerMap.get(dst).forEach((item) => {
            if (item[0] === src) {
              if (minCost === -1 || minCost > item[1]) minCost = item[1];
            }
          });
          if (K === 0) return minCost;
        } else {
          if (K === 0) return -1;
        }

        let stepCount = K + 1;

        //存储当前往前遍历到的结点
        let srcMap = new Map();

        //起点向前走了一步
        if (outerMap.has(src)) {
          outerMap.get(src).forEach((item) => {
            srcMap.set(item[0], item[1]);
          });
        } else {
          return -1;
        }
        stepCount--;

        while (stepCount !== 0) {
          //暂存当前遍历到的结点
          let tmpSrcMap = new Map();
          srcMap.forEach((cost, src) => {
            if (outerMap.has(src)) {
              //往前一步
              outerMap.get(src).forEach((item) => {
                //如果下一步有终点,判断一下价格,比当前最便宜的贵可以剪枝
                if (item[0] === dst) {
                  if (minCost === -1 || item[1] + cost < minCost) {
                    minCost = item[1] + cost;
                  }
                } else {
                  //如果路径价格已经高于当前已得出的最便宜的价格,剪枝
                  if (minCost !== -1) {
                    if (item[1] + cost < minCost) {
                      if (tmpSrcMap.has(item[0])) {
                        if (tmpSrcMap.get(item[0]) > item[1] + cost) {
                          tmpSrcMap.set(item[0], item[1] + cost);
                        }
                      } else {
                        tmpSrcMap.set(item[0], item[1] + cost);
                      }
                    }
                  } else {
                    //注意暂存map中如果已有下一步,判断一下两次得到的价格高低,存较小者
                    if (tmpSrcMap.has(item[0])) {
                      if (tmpSrcMap.get(item[0]) > item[1] + cost) {
                        tmpSrcMap.set(item[0], item[1] + cost);
                      }
                    } else {
                      tmpSrcMap.set(item[0], item[1] + cost);
                    }
                  }
                }
              });
            }
          });
          //如果下一步已经没有航班了,跳出循环
          if (tmpSrcMap.size === 0) {
            break;
          }
          srcMap = tmpSrcMap;
          stepCount--;
        }
        return minCost;
      };

 

posted @ 2020-11-08 21:31  想学JS的前端  阅读(115)  评论(0编辑  收藏  举报