• 回溯 Leetcode 332 重新安排行程


    重新安排行程

    Leetcode 332

    学习记录自代码随想录

    给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
    所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
    例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前。
    假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

    输入:tickets = [[“MUC”,“LHR”],[“JFK”,“MUC”],[“SFO”,“SJC”],[“LHR”,“SFO”]]
    输出:[“JFK”,“MUC”,“LHR”,“SFO”,“SJC”]
    输入:tickets = [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
    输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
    解释:另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”] ,但是它字典排序更大更靠后。

    要点:1.回溯模板上修改一些判断条件;
    2.需要开始对车票排序,之后排过序后只要找到一个方案就是所需的字母排序最小的方案;
    3.检查重复的车票,有的车票会重复;
    4.检查使用过的车票以及车票开头是否等于上次末尾;

    方法一:

    class Solution {
    private:
        // vector path = {"JFK"};
        string start = "JFK";
        vector<vector<string>> result;
    
        void backtracking(vector<vector<string>>& tickets, vector<int> used, vector<string> path){
            if(path.size() == tickets.size() + 1){
                result.push_back(path);
                return;
            }
    
            // start = path.back();
            for(int i = 0; i < tickets.size(); i++){
                // 已经对车票开始排过序了,所以只要找到一个方案就是所需的字母排序最小的方案
                if(result.size() > 0) break;
                // 检查重复的车票,有的车票会重复
                if (i > 0 && !used[i - 1] && tickets[i][0] == tickets[i - 1][0] && tickets[i][1] == tickets[i - 1][1]) {
                    continue;
                }
                // 检查使用过的车票以及车票开头是否等于上次末尾
                if(used[i] == 1 || tickets[i][0] != start){
                    continue;
                }
                start = tickets[i][1];
                used[i] = 1;
                path.push_back(tickets[i][1]);
                backtracking(tickets, used, path);
                path.pop_back();
                start = path.back();
                used[i] = 0;
            }
    
        }
    public:
        vector<string> findItinerary(vector<vector<string>>& tickets){
            // path.clear();
    
            sort(tickets.begin(), tickets.end());
            vector<string> path = {"JFK"};
            vector<int> used(tickets.size(), 0);
            backtracking(tickets, used, path);
            // sort(result.begin(), result.end());
    
            return result[0];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    方法二:使用map存储机票路径

    在这里插入图片描述

    //使用map存储
    class Solution{
    private:
        // 出发机场,<到达机场,标记机场是否使用过>
        unordered_map<string, map<string, int>> targets;
        // 注意此处result需要引用,不然输入的result只是为形参,不改变原来的result
        bool backtracking(vector<string>& result, vector<vector<string>>& tickets){
            if(result.size() == tickets.size() + 1){
                return true;
            }
    
            // target需要引用以对应更改targets, const防止更改
            // for(auto& target : targets[result.back()]){
            for(pair<const string, int>& target : targets[result.back()]){
                if(target.second > 0){
                    result.push_back(target.first);
                    target.second--;
                    if(backtracking(result, tickets)) return true;  // 这样一找到结果就能返回
                    result.pop_back();  // 回溯
                    target.second++;  // 回溯
                }
            }
    
            return false;
        }
    
    public:
        vector<string> findItinerary(vector<vector<string>>& tickets){
            targets.clear();
    
            // 记录映射关系,map是有序的,存储结果自动会排序,1代表没去过,0代表去过
            for(const vector<string>& vec : tickets){
                targets[vec[0]][vec[1]]++;
            }
            vector<string> result;
            result.push_back("JFK");
            backtracking(result, tickets);
    
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    C++基础知识(十)--- I/O
    Windows 10 安装配置WSL2(Ubuntu 20.04)教程
    《羊了个羊》H5游戏开发挑战,3小时LAYA引擎制作核心玩法
    CAx软件中若干C++日志库
    Spring boot 自定义 Starter 及 自动配置
    MySQL中如何计算时间相差的分钟数
    Java系列之:GroupId和ArtifactId的作用
    PostgreSQL数据库配置文件
    c++设计模式:单例模式
    1336. 每次访问的交易次数
  • 原文地址:https://blog.csdn.net/weixin_46930685/article/details/136367054