LeetCode算法题解(回溯、难点)|LeetCode332. 重新安排行程

LeetCode332. 重新安排行程

题目链接:332. 重新安排行程

题目描述:

给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

  • 例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。

假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

示例 1:

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

示例 2:

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

提示:

  • 1 <= tickets.length <= 300
  • tickets[i].length == 2
  • fromi.length == 3
  • toi.length == 3
  • fromi 和 toi 由大写英文字母组成
  • fromi != toi
算法分析:

首先我们可以通过建立一张嵌套的哈希表来记录出发机场和降落机场的映射关系(注意相同的机票可能会出现多张,所以我们也要记录航班的次数)。

Map<String, Map<String, Integer>>map;//Map<出发机场,Map<到达机场,航班次数>>

对map的初始化的代码如下:

map = new HashMap<String, Map<String, Integer>>();
for(List<String> t : tickets) {//将每张机票放入到map的对应关系当中
     Map<String, Integer>tem;
     if(map.containsKey(t.get(0))) {
        tem = map.get(t.get(0));
        tem.put(t.get(1), tem.getOrDefault(t.get(1), 0) + 1);
     }else {
        tem = new TreeMap<>();
        tem.put(t.get(1), 1);
     }
     map.put(t.get(0), tem);
}

然后通过回溯遍历行程,这里要明白行程path中走过的机场次数等于机票数加一。(如示例1的机票数是[["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]],4张,那么行程中所经过的机场数就是5,["JFK","ATL","JFK","SFO","ATL","SFO"])。

所以回溯结束的条件就是当行程(path)的长度等于机票数加一(此时每张机票都用完了),我们返回一个布尔类型true,标记找到合理的行程了。

public boolean backTravel(int num) {
        if(path.size() == num + 1) return true;
}

回溯当中的单层搜索逻辑(遍历一个出发机场对应的所有到达机场)。

遍历过程如下:

String last = path.getLast();//记录当前行程中最后一个机场,当作出发的机场
        if(map.containsKey(last)) {//如果有对应的到达机场,遍历所有的到达机场
            for(Map.Entry<String, Integer>tem : map.get(last).entrySet()) {
                int count = tem.getValue();
                if(count > 0) {//如果航班次数大于0 ,说明还有机票
                    path.add(tem.getKey());//将到达机场放入行程
                    tem.setValue(count - 1);//航班次数-1
                    if(backTravel(num)) return true;//递归,如果递归结果为true,说明已经找到一个合理的形成了,不必在遍历,返回true
                    //回溯
                    path.removeLast();
                    tem.setValue(count);
                }
            }
        }

完整的代码如下:

class Solution {
    LinkedList<String>path;//用来记录合理的行程
    Map<String, Map<String, Integer>>map;//用来记录每张机票是否用过
    //Map<出发机场,Map<到达机场,航班次数>>
    public boolean backTravel(int num) {
        if(path.size() == num + 1) return true;//如果行程的机场数是票数加一,那么说明每一张机票肯定都用完了,返回标记true。
        String last = path.getLast();//记录当前行程中最后一个机场,当作出发的机场
        if(map.containsKey(last)) {//如果有对应的到达机场,遍历所有的到达机场
            for(Map.Entry<String, Integer>tem : map.get(last).entrySet()) {
                int count = tem.getValue();
                if(count > 0) {//如果航班次数大于0 ,说明还有机票
                    path.add(tem.getKey());//将到达机场放入行程
                    tem.setValue(count - 1);//航班次数-1
                    if(backTravel(num)) return true;//递归,如果递归结果为true,说明已经找到一个合理的形成了,不必在遍历,返回true
                    //回溯
                    path.removeLast();
                    tem.setValue(count);
                }
            }
        }
        return false;
    }
    public List<String> findItinerary(List<List<String>> tickets) {
        map = new HashMap<String, Map<String, Integer>>();
        path = new LinkedList<>();
        for(List<String> t : tickets) {//将每张机票放入到map的对应关系当中
            Map<String, Integer>tem;
            if(map.containsKey(t.get(0))) {
                tem = map.get(t.get(0));
                tem.put(t.get(1), tem.getOrDefault(t.get(1), 0) + 1);
            }else {
                tem = new TreeMap<>();
                tem.put(t.get(1), 1);
            }
            map.put(t.get(0), tem);
        }
        path.add("JFK");//将出发的机场首先插入到行程当中
        backTravel(tickets.size());
        return (List)path;

    }
}

总结

这道题算是比较难了,主要还是需要理解双层(嵌套)哈希表的逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/126577.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uboot启动linux kernel的流程

目录 前言流程图autoboot_commandrun_command_listdo_bootmdo_bootm_statesdo_bootm_linuxboot_prep_linuxboot_jump_linux 前言 本文在u-boot启动流程分析这篇文章的基础上&#xff0c;简要梳理uboot启动linux kernel的流程。 流程图 其中&#xff0c; autoboot_command位于…

Error creating bean with name ‘apiModelSpecificationReader‘ defined in URL

问题&#xff1a; 启动项目的时候&#xff0c;报错了 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name apiModelSpecificationReader defined in URL [jar:file:/D:/.gradle/caches/modules-2/files-2.1/io.springfox/sp…

【亚马逊云科技产品测评】活动征文|10分钟拥有一台AWS Linux系统

前言 在数字化时代&#xff0c;AWS云服务扮演着至关重要的角色。AWS&#xff08;Amazon Web Services&#xff09;是亚马逊公司旗下的云计算服务平台&#xff0c;为全球各地的企业、组织和个人开发者提供了一系列广泛而深入的云服务。 在AWS云服务中&#xff0c;计算、存储、数…

selenium css定位

selenium-css定位 element_css driver.find_element(By.CSS_SELECTOR, css表达式)css定位说明 selenium中的css定位&#xff0c;实际是通过css选择器来定位到具体元素&#xff0c;css选择器来自于css语法 css定位优点 语法简洁对比其他定位方式&#xff0c;定位效率更快对…

「Java开发指南」如何用MyEclipse搭建Spring MVC应用程序?(二)

本教程将指导开发者如何生成一个可运行的Spring MVC客户应用程序&#xff0c;该应用程序实现域模型的CRUD应用程序模式。在本教程中&#xff0c;您将学习如何&#xff1a; 从数据库表的Scaffold到现有项目部署搭建的应用程序 使用Spring MVC搭建需要MyEclipse Spring或Bling授…

发电机负载测试:专业指南

发电机负载测试是一项关键的测试过程&#xff0c;发电机负载测试的专业指南&#xff0c;帮助您进行有效的测试。 测试前准备&#xff1a;确保发电机和测试设备处于良好的工作状态&#xff0c;检查发电机的电源和燃料供应是否正常&#xff0c;确保测试设备和发电机之间的连接正确…

Unity Mirror学习(二) Command特性使用

Command&#xff08;命令&#xff09;特性 1&#xff0c;修饰方法的&#xff0c;当在客户端调用此方法&#xff0c;它将在服务端运行&#xff08;我的理解&#xff1a;客户端命令服务端做某事&#xff1b;或者说&#xff1a;客户端向服务端发消息&#xff0c;消息方法&#xff…

高能数造电池3D打印智能制造小试线,开启全固态电池数字化新时代

在科技创新的浪潮中&#xff0c;电池制造领域又迎来了一次突破性的进展。近日&#xff0c;高能数造(西安)技术有限公司重磅推出了其最新电池数字制造装备——全固态电池3D打印智能制造小试线 &#xff0c;这一创新性的技术开启了全固态电池的数字化智造新时代&#xff0c;为全固…

【ElasticSearch系列-06】Es集群架构的搭建以及集群的核心概念

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…

如何提高小红书笔记的互动率

相信有很多新手在运营小红书的时候&#xff0c;可能都会遇到过以下这样的情况&#xff1a; 笔记点赞、收藏数据明明还可以&#xff0c;但评论区却没有人留言&#xff1f;为何大家只给点赞、收藏&#xff0c;却不关注账号&#xff1f; 其实&#xff0c;这背后有很多运营技巧&a…

怎么调整excel表里面所有单元格中,某个相同字体大小,单元格中其他文字大小不变?

环境: excel 2021 python3.8 问题描述: 怎么调整excel表里面所有单元格里面1这个字体大小,单元格里面其他文字不变? excel表里面。很多单元格都有1,1和文字都是10号字体,现在想把全部1字字体调整为16号其他字大小都不变 解决方案: 一、使用python来实现,经过测…

caffe搭建squeezenet网络的整套工程

之前用pytorch构建了squeezenet&#xff0c;个人觉得pytorch是最好用的&#xff0c;但是有的工程就是需要caffe结构的&#xff0c;所以本篇也用caffe构建一个squeezenet网络。 数据处理 首先要对数据进行处理&#xff0c;跟pytorch不同&#xff0c;pytorch读取数据只需要给数据…

Java 设计模式——解释器模式

目录 1.概述2.结构3.案例实现3.1.抽象表达式类3.2.终结表达式3.3.非终结表达式3.4.环境类3.5.测试 4.优缺点5.使用场景 1.概述 &#xff08;1&#xff09;如下图&#xff0c;设计一个软件用来进行加减计算。我们第一想法可能就是使用工具类&#xff0c;提供对应的加法和减法的…

2023最新版JavaSE教程——第5天:数组

目录 一、数组的概述1.1 为什么需要数组1.2 数组的概念1.3 数组的分类 二、一维数组的使用2.1 一维数组的声明2.2 一维数组的初始化2.2.1 静态初始化2.2.2 动态初始化 2.3 一维数组的使用2.3.1 数组的长度2.3.2 数组元素的引用 2.4 一维数组的遍历2.5 数组元素的默认值 三、一维…

03【远程协作开发、TortoiseGit、IDEA绑定Git插件的使用】

上一篇&#xff1a;02【Git分支的使用、Git回退、还原】 下一篇&#xff1a;【已完结】 目录&#xff1a;【Git系列教程-目录大纲】 文章目录 一、远程协作开发1.1 远程仓库简介1.1.1 Github1.1.2 Gitee1.1.3 其他托管平台 1.2 发布远程仓库1.2.1 创建项目1&#xff09; 新…

解决:AttributeError: ‘WebDriver‘ object has no attribute ‘find_element_by_xpath‘

解决&#xff1a;AttributeError: ‘WebDriver’ object has no attribute ‘find_element_by_xpath’ 背景 在使用之前的代码通过selenium定位元素时&#xff0c;报错&#xff1a;selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to l…

Altium Designer学习笔记1

一、新建项目和文件&#xff1a; 1、新建Project项目&#xff1b; 2、新建原理图文件&#xff1b; 3、新建PCB项目&#xff1b; 在工程文件上点击右键&#xff0c;保存为&#xff0c;可以依次保存三个文件。选择需要保存的路径&#xff0c;新建文件夹。 依次是原理图文件、…

如何用Java高效地存入一万条数据?这可能是你面试成功的关键!

大家好&#xff0c;我是你们的小米&#xff0c;一个热爱技术、喜欢分享的29岁程序猿。今天我要和大家聊一聊一个常见的面试题&#xff1a;在Java中&#xff0c;当我们需要将一万条数据存储到数据库时&#xff0c;如何能够提高存储效率呢&#xff1f; 在面试过程中&#xff0c;…

事务(本地事务与分布式事务)

事务 1 本地事务1.1 事务的特性1.2 事务的隔离级别1.3 事务的传播属性 2 分布式事务2.1 分布式事务基础2.1.1 CAP定理2.1.2 BASE定理 2.2 分布式事务的解决方案2.2.1 两阶段提交&#xff08;2PC&#xff09;2.2.2 TCC补偿式事务2.2.3 消息事务最终一致性 1 本地事务 1.1 事务的…

Mysql视图应用

现在&#xff0c;我们将创建一个视图&#xff0c;将员工的姓名、部门和工资信息组合在一起。 CREATE VIEW EmployeeSalaryView AS SELECT e.FirstName, e.LastName, e.Department, s.MonthlySalary FROM Employees e JOIN Salary s ON e.EmployeeID s.EmployeeID;通过这个视图…