其他分享
首页 > 其他分享> > 【JS力扣刷题笔记】332. 重新安排行程

【JS力扣刷题笔记】332. 重新安排行程

作者:互联网

这是跟着代码随想录的顺序学习算法的第三十二天。

以下是学习时自己的一些理解与笔记,如有错误欢迎指正与讨论。


332. 重新安排行程

参考相关链接:

332. 重新安排行程

代码随想录


笔记

在自己做本题的时候,写出来的解法超时了,原因是我先找到了所有路径存入一个数组,再将其进行排序,输出字典排序最小的那个行程。

接着,我稍作修改,不把所有的路径存入数组中,而是保证结果中只有一个路径存在,找到另一条完整路径和就进行比较,看是否需要替换结果中的路径。结果,还是超时了。

上面两种尝试超时的根本原因在于,都是需要找出所有路径后,再考虑字典排序。

但是,只需要找出一条路径即可,按照代码随想录中给的思路,就是先进行了排序,保证了找到了的第一条可行的路径一定就是最短的。

(正确的解法放这里,超时的解法放后面了)


// 根据 代码随想录 中JS版本进行了修改,在关键地方加了自己的理解注释

var findItinerary = function(tickets) {
    const res = ["JFK"];
    let map = {};
    for(const [from, to] of tickets) {
        if(!map[from]) {
            map[from] = [];
        }
        map[from].push(to);
    }
    // 先按字典顺序排序, 就能保证找到的第一条路径就是最短的
    for(const city in map) {
        map[city].sort();
    }
    // 返回 bool 类型, 因为只需要找到一条路径即可, 不需要全部遍历一次
    function backtracking() {
        if(res.length === tickets.length + 1) return true;
        // 注意: 地图中可能不存在属性名为 res[res.length - 1] 的属性
        // 因此不一定有length属性, 故不可单靠 for 循环来判断
        if(!map[res[res.length - 1]] || !map[res[res.length - 1]].length) return false;
        for(let i = 0; i < map[res[res.length - 1]].length; i++) {
            // 先将本次循环会用到的目的地从 map 中删除, 防止死循环
            const city = map[res[res.length - 1]][i];
            // splice 是返回被删的部分元素组成的数组 (可为空数组)
            map[res[res.length - 1]].splice(i,1);
            res.push(city);
            // 找到第一条路径就直接返回, 退出回溯
            if(backtracking()) return true;
            res.pop();
            // 没有成功找到有效行程, 把 city 加回 map 去
            map[res[res.length - 1]].splice(i, 0, city);
        }
    }
    backtracking();
    return res;
};

// 这是超时的解法

var findItinerary = function(tickets) {
    const res = [];
    let used = Array(tickets.length).fill(false);
    const temp = [];
    // 输入票 已使用情况
    function backtracking(tickets, used) {
        // 行程长度来判断终止
        if(temp.length === tickets.length + 1) {
            if(!res.length || res[0] > temp) {
                res.pop();
                res.push([...temp]);
            }
            // res.push(...temp);
            return;
        }

        for(let i = 0; i < tickets.length; i++){
            // 不得再用
            // 第一个就输入两个 JFK 开头
            // temp结尾 与 ticket[i]开头 是否相同
            if(used[i]) continue;
            if(!temp.length) {
                if(tickets[i][0] === "JFK") {
                    temp.push(tickets[i][0]);
                    temp.push(tickets[i][1]);
                    used[i] = true;
                    backtracking(tickets, used);
                    used[i] = false;
                    temp.pop();
                    temp.pop();
                }
            } else {
                if(tickets[i][0] === temp[temp.length - 1]) {
                    temp.push(tickets[i][1]);
                    used[i] = true;
                    backtracking(tickets, used);
                    used[i] = false;
                    temp.pop();
                }
            }
        }
        return;
    }
    backtracking(tickets, used);
    // res.sort();
    return res[0];
};

标签:tickets,map,used,temp,res,JS,力扣,length,332
来源: https://blog.csdn.net/Jamcy123/article/details/123581372