//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; };