代码随想录算法训练营第三十天| 332.重新安排行程、回溯总结

news2024/12/26 12:03:04

文章目录

      • 332.重新安排行程:star:
      • 回溯总结:star:
        • 1.组合问题
        • 2.切割问题
        • 3.子集问题
        • 4.排列问题
        • 5.棋盘问题(未完待续)
        • 6.复杂度分析

332.重新安排行程⭐️

  • 链接:代码随想录

本题是一道困难题,其实困难点也就在容器的选择和使用上

  1. 结果集采用数组存取即可
  2. 操作集要用一个map集合存储,Map<出发机场,Map<目的机场,目的机场所用次数>>,将两个数据关联起来要选取Map集合
  • 关键点:

    1. 回溯法返回值:返回boolean值,目的为只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线,所以找到了这个叶子节点了直接返回,有返回值可以根据底层传上来的值在当前节点做出判断和抉择。
    2. 接收值:一个res数组集合即可,因为只需要收集一条路径
  • 解题思路:

    ①主函数方面:一个Map集合中维护了源机场和目的机场之间的关系,目的机场信息又维持了一个map集合,记录相关信息
    ②回溯函数方面:
    1. 返回值:返回boolean值,为了剪枝,因为只需要一条最佳路径即可
    2.终止条件,当tickets.size() + 1 即要经过的所有机场数 等于 res.size(沿途所经过的所有机场数)
    3.处理逻辑:
    ①一定要先判断res中的最后一个值有没有包含在大map集合中,如果没有直接返回false,终止这一层遍历image-20230413174700281
    ②如果map中存在源机场信息,那么接下来要做的就是从维护的目的机场map中挑选一个排序靠前的机场(TreeMap已实现)
    进行加入,然后递归下一层的机场(如果返回true,说明路径可选,直接一层层归回去结束)

  • 图像理解:

    2023-04-13T16_10_20

    1.用处理次数来解决

    2.用一个TreeMap集合来存储目的机场,遍历的时候先遍历排序靠前的

    3.如果结果集中机场个数大于目标值返回

    4.采用回溯遍历

    image-20230413173651285

    2023-04-13T16_11_02

    2023-04-13T16_13_49

    2023-04-13T16_15_24

public class Solution {

    private LinkedList<String> res = new LinkedList<>();
    private Map<String,Map<String,Integer>> map = new HashMap<>();//用来存放一个机场飞往下一个机场的航班和次数

    public List<String> findItinerary(List<List<String>> tickets) {

        //处理数据,放入map集合中存储每个机场飞往下一个机场的航班信息
        for(List<String> ticket : tickets){

            Map<String,Integer> temp;//用来添加下一班机场的名字和次数

            if(map.containsKey(ticket.get(0))){//存在当前机场
                //进行获取map中key为ticket的值
                temp = map.get(ticket.get(0));
                //先把目的机场放进去,再判断如果temp中有string,则按默认value放 + 1;否则按0 + 1
                temp.put(ticket.get(1), temp.getOrDefault(ticket.get(1), 0) + 1);

                //放入temp值
                map.put(ticket.get(0), temp);
            }else{
                temp = new TreeMap();//建立一棵排好序的树
                temp.put(ticket.get(1), 1);
                map.put(ticket.get(0), temp);
            }

        }


        res.add("JFK");
        backtracking(tickets.size());

        return new ArrayList<>(res);

    }

    private boolean backtracking(int ticketNum) {

        //终止条件
        if(res.size() == ticketNum + 1){
            return true;//检测到true才直接往上放回
        }

        String last = res.getLast();


        if(map.containsKey(last)){//防止出现null的情况

            //进入处理逻辑,这里面的target已经按顺序排好,因为是target存储在TreeMap集合中
            for(Map.Entry<String,Integer> target : map.get(last).entrySet()){
                int count = target.getValue();

                if(count > 0){//每个字符串数组只能用一次
                    res.add(target.getKey());

                    target.setValue(count - 1);

                    //回溯过程,如果传过来的数据为true,直接返回递归的一条分支,不再回溯和for循环
                    if(backtracking(ticketNum)){
                        return true;
                    }

                    //回溯
                    res.removeLast();
                    target.setValue(count);
                }
            }

        }

        //用来表示这一分支的最终结果
        return false;

    }
}

回溯总结⭐️

  • 题目链接:代码随想录

回溯是递归的副产品,只要有递归就会有回溯

  1. 整体题目:

    image-20230413191641668

  2. for循环遍历的时候什么时候加上startIndex?

    • 组合问题:

      如果是一个集合来求组合的话,就需要startIndex,如求一个组合和的问题

      如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,如求多组电话号码和的问题

1.组合问题

    1. 求解
image-20230413191801968

​ 2. 剪枝:

image-20230413192024754

  • 组合总和问题

    image-20230413192318243

  • 组合总和(三)—>集合中有重复元素

    image-20230413192730526

  • 电话问题—>多个集合求组合

    image-20230413192932655

2.切割问题

  • 用求解组合问题的思路来解决

    image-20230413193232722

    image-20230413193247795

3.子集问题

  • 在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果

  • 普通子集问题一定要排序,不能简单用哈希数组去重,因为

    image-20230413193729175

    与递增子序列区分开来

  1. 子集问题(一)

    image-20230413193357862

  2. 子集问题(二)

    image-20230413193450423

  3. 递增子序列

    • 特点为:不能是排好序的数组,要借助哈希数组,层间去重,与子集问题区分开来
    • image-20230413193915165

4.排列问题

  • 特点:
    • 每层都是从0开始搜索而不是startIndex
    • 需要used数组记录path里都放了哪些元素了(树枝去重
  1. 普通排列:

    image-20230413194102347

  2. 排列问题(树层去重)

    image-20230413194151557

5.棋盘问题(未完待续)

6.复杂度分析

image-20230413194635060

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法篇——栈与队列大集合(js版)

232.用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int…

SpringBoot集成Redis及问题解决

SpringBoot集成Redis 此篇文章为SpringBoot集成Redis的简单介绍&#xff0c;依赖、序列化操作、工具类都可以在后面的实操中直接搬运使用或者在此基础上进行改进使用 1、集成Redis 1.1、新建SpringBoot项目 新建项目这边就不一一介绍了&#xff0c;大家如果还有不会的可以自行…

【LeetCode】144.二叉树的前序遍历

1.问题 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;root [1]…

七大排序的时间复杂度和空间复杂度

文章目录 七大排序的分类时间复杂度空间复杂度稳定性直接插入排序希尔排序选择排序堆排序冒泡排序快速排序归并排序总结 七大排序的分类 时间复杂度 时间复杂度是指一个程序中基本语句被执行的次数,一般认为是最坏情况。 空间复杂度 空间复杂度是指在一个程序执行时要额外开…

美团DAT:A Dual Augmented Two-tower Model for Online Large-scale Recommendation

A Dual Augmented Two-tower Model for Online Large-scale Recommendation 美团的对偶增强双塔为了user塔和item塔操碎了心&#xff0c;众所周知&#xff0c;双塔的一个大毛病就是item和user的交叉太晚&#xff0c;重要的信息经过层层神经网络的抽象提取&#xff0c;有些重要…

15、异常处理

文章目录 1、错误处理1、默认规则2、定制错误处理逻辑3、异常处理自动配置原理4、异常处理步骤流程 【尚硅谷】SpringBoot2零基础入门教程-讲师&#xff1a;雷丰阳 笔记 路还在继续&#xff0c;梦还在期许 1、错误处理 1、默认规则 默认情况下&#xff0c;Spring Boot提供/er…

傻傻的分不清 Comparator 和 Comparable 接口? 两分钟弄懂~

目录 一、Comparable 接口 二、Comparator 接口 一、Comparable 接口 Comparable 是一个排序接口&#xff08;意味着该支持排序&#xff09;&#xff0c;可以看作内比较器&#xff0c;也就是说可以和自己比较&#xff0c;通常用来自己属性与自己属性进行比较&#xff0c;最后通…

百年孤独 -- 有感

《创世记》之后&#xff0c;首部值得全人类阅读的文学巨著。 — 纽约时报 加西亚 马尔克斯以小说作品创建了一个自己的世界&#xff0c;一个浓缩的宇宙&#xff0c;其中喧嚣纷乱却又生动可信的现实&#xff0c;映射了一篇大陆及其人民的富足与贫困。 — 诺贝尔文学奖颁奖辞 马…

wordpress+apache搭建问题总结

访问首页出现服务器目录 需要到apache的httpd.conf 添加index.php默认值 更新失败。 此响应不是合法的JSON响应 大多出现于修改固定连接后 打开httpd.conf文件,把AllowOverride None修改为AllowOverride All,重启apache即可解决 AllowOverride Noneyi意味着忽略.htaccess文件…

VS2022中创建C++SDK库(dll动态库)并调用SDK库(dll动态库)

VS2022中创建CSDK库(dll动态库)并调用SDK库(dll动态库) 一、说明 通过前两篇的文章我们知道了封装一个Qt下的SDK库&#xff08;dll动态链接库&#xff09;和封装Pimpl模式。 Qt创建SDK库(dll动态库)并调用SDK库(dll动态库) SDK(动态链接库dll)的封装技巧 本篇介绍在C VS下…

深度解析动态分配内存管理

目录 ​编辑 一. 前言 二.正文 2.0 计算机中的内存 2.1 动态申请函数头文件 2.2 malloc函数 2.3 free函数 2.3 calloc函数 2.4 realloc函数 2.5 经典笔试题 1. 2. 2.6 柔性数组 三.结语 一. 前言 本小节跟大家分享动态内存管理的知识&#xff0c;希望能给大家带…

2020年全国10m分辨率地表覆盖数据集

1.数据概况 地球观测技术的进步使得土地覆盖制图的空间分辨率不断提高&#xff0c;但这也导致了高分辨率影像样本收集和更新变得更加耗时。本研究提出了一种基于样本噪声学习的跨分辨率土地覆盖制图框架&#xff0c;利用现有低分辨率产品生成大量高分辨率影像标签用于深度语义…

【Python从入门到进阶】17、文件的读写操作

接上篇《16、文件的打开和关闭》 上一篇我们学习了Python打开和关闭文件的操作。本篇我们主要学习Python文件对象包含哪些方法&#xff0c;并学习文件如何进行读、写、定位和删除。 一、文件对象的属性和方法 通过上一篇的学习我们知道&#xff0c;open函数会返回给我们一个文…

一个简单的盒模型嵌套---一个大盒子里面嵌套两个中盒子,右边中盒子嵌套六个小盒子

html代码&#xff1a; <div class"box1"><div class"box2"></div><div class"box3"><div class"box4"></div><div class"box5"></div><div class"box6">&…

apple pencil值不值得购买?ipad平替电容笔安利

自从Apple Pencil上市后&#xff0c;平替电容笔在国内的销量&#xff0c;也是随之而增加&#xff0c;虽然Apple Pencil的性能不错&#xff0c;但由于其的价格太高&#xff0c;所以不少普通用户都买不起。现在市面上有很多能够代替苹果原装笔的平替电容笔。在这里&#xff0c;我…

Debezium系列之:自定义表级别Topic的名称

Debezium系列之:自定义表级别Topic的名称 一、需求背景二、去掉部分topic名称的方法三、debezium具体实现方法四、完整配置一、需求背景 debezium表级别Topic命名规则为:topic.prefix参数的值.数据库名称.表的名称现在支持实时需求,命名名称需要修改为topic.prefix参数的值.…

SAP KANBAN 从入门到放弃系列之生产补货模式

目录 系统操作 看板牌-生产补货 系统配置&#xff1a; 补充策略配置 看板状态配置 创建物料主数据 创建供应区域 创建控制周期-经典看板 系统操作 看板牌-生产补货 需要必要的看板配置和主数据设置 第一步&#xff1a;事务代码:PK13N&#xff0c;需求端KANBAN.供应端…

【数据库】 | 初始数据库

&#x1f397;️ 博客新人&#xff0c;希望大家一起加油进步 &#x1f397;️ 乾坤未定&#xff0c;你我皆黑马 目录 1、什么是数据库2、数据库分类3、 一些重要概念4、 数据存储 1、什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以…

访京东查询(自定义查询,组件形式,多页面使用,自定义查询条件)

1、效果图 2、使用了Ant Design of Vue里面的tag属性&#xff0c;也可以不用自己写样式。 3、代码模块 1、创建一个公共组件vue文件 <template><a-card size"small" :bordered"false" style"margin-bottom: 10px; padding:0px;">&l…

SVG格式文件可以用什么软件打开?

SVG是一种基于矢量的图像文件格式&#xff0c;通过基于网格上的点和线的数学公式存储图像&#xff0c;与 JPEG 等基于像素的位图文件不同。这种文件类型可以在不损失任何质量的情况下生成很小的文件&#xff0c;因而加载速度也相对更快&#xff0c;也使其成为LOGO和复杂在线图形…