【做一道算一道】力扣332.重新安排行程

332.重新安排行程

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。

提示:

如果存在多种有效的行程,请你按字符自然排序返回最小的行程组合。例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前

所有的机场都用三个大写字母表示(机场代码)。

假定所有机票至少存在一种合理的行程。

所有的机票必须都用一次 且 只能用一次。

示例 1:

输入:[["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]

输出:["JFK", "MUC", "LHR", "SFO", "SJC"]

示例 2:

输入:[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]

输出:["JFK","ATL","JFK","SFO","ATL","SFO"]

解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。

思路

代码随想录 332.重新安排行程

做不了一点,跟着代码随想录刷的,这个题感觉用到了好多东西,记一下。

特别里面的嵌套结构,看的有点绕,记一下理解的结果。

代码

cpp 复制代码
class Solution {
private:
    //                               unordered_map<string, map<string, int>> targets:
    //出发机场->{到达机场->航班次数}  unordered_map<出发机场, map<到达机场, 航班次数>> targets
    unordered_map<string,map<string,int>> targets;
    vector<string> res;
    bool backtracking(int ticketNum,vector<string>& res){
        if(res.size()==ticketNum+1){  //类似插缝,机场数比航班数多一
            return true;
        }
        for(pair<const string,int>& target:targets[res[res.size()-1]]){
            if(target.second>0){ //还能飞
                res.push_back(target.first);
                target.second--;
                if(backtracking(ticketNum,res))
                return ture;
                res.pop_back();
                target.second++;
            }
        }
        return false;
    }
public:
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        //tickets结构=[[出发机场,到达机场]]
        //tickets = [["string","string"]]
        for(const vector<string>& vec:tickets){
            targets[vec[0]][vec[1]]++;  //int类型的默认初始化是0
        }
        res.push_back("JFK");
        backtracking(tickets.size(),res);
        return res;
    }
};

理解

unordered_map<出发机场, map<到达机场, 航班次数>> targets

内层选map使得到达机场(key)是有序的,最终的结构符合字典序

unordered_map<string, map<string, int>> targets的结构理解:

设tickets={

["JFK", "LAX"],

["JFK", "SFO"],

["LAX", "SFO"],

["JFK", "LAX"]

}

则,targets = {

"JFK" => {

"LAX" => 2,

"SFO" => 1

},

"LAX" => {

"SFO" => 1

}

}

即这个最里面的map是到达机场是键(key),航班次数是值(value),然后这一对key-value又是外层unordered_map的value,key是出发机场,这样的一个两层嵌套结构。

假如用表格表示的话大概如下表(直观表示,实际是嵌套关系):

出发机场 到达机场 航班次数
JFK LAX 2
JFK SFO 1
LAX SFO 3
cpp 复制代码
for(const vector<string>& vec:tickets){
            targets[vec[0]][vec[1]]++;  //int类型的默认初始化是0
        }

targets没有初始化的情况下,int类型默认值为0

vec[0]vec[1]对应上面表格的出发机场和到达机场

cpp 复制代码
res.push_back("JFK");
cpp 复制代码
       for(pair<const string,int>& target:targets[res[res.size()-1]]){
            if(target.second>0){ //还能飞
                res.push_back(target.first);
                target.second--;
                if(backtracking(ticketNum,res))
                return ture;
                res.pop_back();
                target.second++;
            }
        }

因为res在函数中初始化了以"JFK"为初值(题意,"JFK"为起始机场),所以一开始在已经初始化了的targets中查找航班次数就从"JFK"开始,逐个优先按字典序查找可行的航班路径。

相关推荐
我是哈哈hh1 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy1 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java1 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli1 小时前
滑动窗口->dd爱框框
算法
丶Darling.1 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5202 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
jiyisuifeng19912 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法
꧁༺❀氯ྀൢ躅ྀൢ❀༻꧂2 小时前
实验4 循环结构
c语言·算法·基础题
新晓·故知2 小时前
<基于递归实现线索二叉树的构造及遍历算法探讨>
数据结构·经验分享·笔记·算法·链表
总裁余(余登武)3 小时前
算法竞赛(Python)-万变中的不变“随机算法”
开发语言·python·算法