回溯 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.检查使用过的车票以及车票开头是否等于上次末尾;

方法一:

cpp 复制代码
class Solution {
private:
    // vector<string> 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];
    }
};

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

cpp 复制代码
//使用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;
    }
};
相关推荐
山登绝顶我为峰 3(^v^)31 小时前
如何录制带备注的演示文稿(LaTex Beamer + Pympress)
c++·线性代数·算法·计算机·密码学·音视频·latex
Two_brushes.2 小时前
【算法】宽度优先遍历BFS
算法·leetcode·哈希算法·宽度优先
森焱森4 小时前
水下航行器外形分类详解
c语言·单片机·算法·架构·无人机
QuantumStack6 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
写个博客6 小时前
暑假算法日记第一天
算法
绿皮的猪猪侠6 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
hie988947 小时前
MATLAB锂离子电池伪二维(P2D)模型实现
人工智能·算法·matlab
杰克尼7 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
.30-06Springfield8 小时前
决策树(Decision tree)算法详解(ID3、C4.5、CART)
人工智能·python·算法·决策树·机器学习
我不是哆啦A梦8 小时前
破解风电运维“百模大战”困局,机械版ChatGPT诞生?
运维·人工智能·python·算法·chatgpt