代码随想录算法训练营之JAVA|第二十六天| 332. 重新安排行程

news2024/11/26 0:56:40

今天是第26天刷leetcode,立个flag,打卡60天。

算法挑战链接

332. 重新安排行程icon-default.png?t=N6B9https://leetcode.cn/problems/reconstruct-itinerary/

第一想法

题目理解:将多个行程的ticket 用第一个行程的结束地点作为下一个行程的开始地点,将行程串联起来。要求一次ticket只能使用一次,且必须将所有ticket使用完。

这种题目就是无脑套用回溯算法。我就会根据回溯算法的三步曲来走

第一步:确定返回值和入参。返回值是 void 入参是:tickets 、 tickets的标记 和 开始的位置

void backtracking5(String start, List<List<String>> tickets, int[] index)

第二步:确定终止条件:当所有的tickets都被用完了,就可以结束了

        if (resultTmp5.size() + 1 == tickets.size()) {
                ......
                ......
        }

 第三步:当前递归需要完成的事情:当找到合适的ticket,在结果列表中添加,将改ticket的位置置为已使用,进入下一个递归。递归完后恢复,结果列表中移除该ticket,将改ticket的位置置为未使用

       for (int i = 0; i < index.length; i++) {
            if (index[i] == 1) {
                continue;
            }
            if (tickets.get(i).get(0).equals(start)) {
                resultTmp5.add(tickets.get(i).get(1));
                index[i] = 1;
                backtracking5(tickets.get(i).get(1), tickets, index);
                resultTmp5.removeLast();
                index[i] = 0;
            }
        }

于是代码就写出来了如下:

class Solution {
    LinkedList<String> resultTmp5 = new LinkedList<>();
    List<String> result5 = new ArrayList<>();
    public List<String> findItinerary(List<List<String>> tickets) {
        resultTmp5.add("JFK");
        backtracking5("JFK", tickets, new int[tickets.size()]);
        return result5;
    }

    void backtracking5(String start, List<List<String>> tickets, int[] index) {
        if (resultTmp5.size() - 1 == tickets.size()) {
            result5 = getMinResult(resultTmp5, result5);
        }

        for (int i = 0; i < index.length; i++) {
            if (index[i] == 1) {
                continue;
            }
            if (tickets.get(i).get(0).equals(start)) {
                resultTmp5.add(tickets.get(i).get(1));
                index[i] = 1;
                backtracking5(tickets.get(i).get(1), tickets, index);
                resultTmp5.removeLast();
                index[i] = 0;
            }
        }
        
    }
    private List<String> getMinResult(LinkedList<String> resultTmp5, List<String> result5) {
        if (result5.isEmpty()) {
            return new ArrayList<>(resultTmp5);
        }
        for (int i = 0; i < resultTmp5.size(); i++) {
            if (resultTmp5.get(i).compareTo(result5.get(i)) > 0) {
                return result5;
            }else if (resultTmp5.get(i).compareTo(result5.get(i)) < 0) {
                return new ArrayList<>(resultTmp5);
            }
        }
        return result5;
    }
}

 但是并没有出现理想中的AC的结果。给力一个超出时间限制的结果。

看完代码随想录之后的想法 

苦思冥想还是想不出来。好难呀。

对比了代码随想录的java代码之后,发现他的递归函数居然需要返回值?我和他的代码差就差在这里了。为啥需要返回值?

他给出的解释是:因为找到一条路径之后就需要在去遍历其他路径了。

对于这个解释我有点好奇,仔细对比之后发现,tickets在开始之前进行过一轮排序。所以如果找到了一条,那么这一条就是正确的答案了。

代码如下:

class Solution {
    LinkedList<String> resultTmp5 = new LinkedList<>();
    List<String> result5 = new ArrayList<>();
    public List<String> findItinerary(List<List<String>> tickets) {
        Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1)));
        resultTmp5.add("JFK");
        backtracking5("JFK", tickets, new int[tickets.size()]);
        return result5;
    }

    boolean backtracking5(String start, List<List<String>> tickets, int[] index) {
        if (resultTmp5.size() -1 == tickets.size()) {
            result5 = getMinResult(resultTmp5, result5);
            return true;
        }

        for (int i = 0; i < index.length; i++) {
            if (index[i] == 1) {
                continue;
            }
            if (tickets.get(i).get(0).equals(start)) {
                resultTmp5.add(tickets.get(i).get(1));
                index[i] = 1;
                if (backtracking5(tickets.get(i).get(1), tickets, index)) {
                    return true;
                }
                resultTmp5.removeLast();
                index[i] = 0;
            }
        }
        return false;
    }

    private List<String> getMinResult(LinkedList<String> resultTmp5, List<String> result5) {
        if (result5.isEmpty()) {
            return new ArrayList<>(resultTmp5);
        }
        for (int i = 0; i < resultTmp5.size(); i++) {
            if (resultTmp5.get(i).compareTo(result5.get(i)) > 0) {
                return result5;
            }else if (resultTmp5.get(i).compareTo(result5.get(i)) < 0) {
                return new ArrayList<>(resultTmp5);
            }
        }
        return result5;
    }
}

今日收获

并不是所有的回溯算法都是不需要返回值的。那哪些需要返回值,这里抄了一下其他人写的:

  • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(本题的情况)

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

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

相关文章

人工智能轨道交通行业周刊-第55期(2023.8.7-8.13)

本期关键词&#xff1a;北京智慧交通规划、成都数智化规划、关门车、集装箱标志、大模型隐私、视觉大模型 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交…

定量分析计算51单片机复位电路工作原理

下面画出等效电路图 可以知道单片机内必然有一个电阻RX&#xff0c;为了简化分析&#xff0c;我们假设他是线性电阻&#xff08;不带电容&#xff0c;电感的支路&#xff09; 还有一个基础知识&#xff1a; 电容器的充电放电曲线&#xff1a; 还需要知道电容电压的变化是连续…

【链表】经典链表题LeetCode

文章目录 160. 相交链表 简单&#x1f525;206. 反转链表 简单&#x1f525;876. 链表的中间结点 简单234. 回文链表 简单&#x1f525;141. 环形链表 简单&#x1f525;142. 环形链表 II 中等&#x1f525;21. 合并两个有序链表 简单&#x1f525;2. 两数相加 中等&#x1f52…

AI Chat 设计模式:14. 适配器模式

本文是该系列的第十四篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 关于适配器模式&#xff0c;如果由浅入深的来考察&#xff0c;你会依次提出什么问题…

Linux零基础快速入门到精通

一、操作系统概述 二、初始Linux Linux的诞生 Linux内核 Linux发行版 小结 三、虚拟机 认识虚拟机 虚拟化软件及安装 VMware Workstation 17 Pro安装教程https://blog.csdn.net/weixin_62332711/article/details/128695978 远程连接Linux系统 小结 扩展-虚拟机快照 …

剑指offer14-II.剪绳子II

这道题和上一道题剪绳子I是一样的&#xff0c;只是数据的规模变大了&#xff0c;由上一题可知&#xff0c;要使得乘积最大就是要尽可能的把它分成全是3的段&#xff0c;如果绳子长度刚好是3的倍数就全部分成3&#xff0c;如果对3取余是2&#xff0c;那就把它分成一个2剩下的全分…

Linux命令200例:dd命令详解及实际应用场景

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

nginx禁用3DES和DES弱加密算法

nginx禁用3DES和DES弱加密算法 项目背景 最近护网行动&#xff0c;收到漏洞报告&#xff0c;如下&#xff1a; 漏洞名称SSL/TLS协议信息泄露漏洞(CVE-2016-2183)【原理扫描】详细描述TLS是安全传输层协议&#xff0c;用于在两个通信应用程序之间提供保密性和数据完整性。 TLS…

【vue2类型助手】vue2-cli 实现为 vue2 项目中的组件添加全局类型提示

实现 vue2 全局组件提示 vue2 项目全局注册组件直接使用没有提示 由于vue2中使用volar存在很大的性能问题&#xff0c;所以只能继续使用vetur&#xff0c;但是这样全局组件会没有提示&#xff0c;这对于开发来说&#xff0c;体验十分不友好&#xff0c;所以开发此cli并借助ve…

时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍 Matlab实现LSTM长短期记忆神经…

OpenCV基本操作——算数操作

目录 图像的加法图像的混合 图像的加法 两个图像应该具有相同的大小和类型&#xff0c;或者第二个图像可以是标量值 注意&#xff1a;OpenCV加法和Numpy加法之间存在差异。OpenCV的加法是饱和操作&#xff0c;而Numpy添加的是模运算 import numpy as np import cv2 as cv imp…

k8s 自身原理 4

前面咱们分享了 mater 和 worker 节点里面都有哪些组件&#xff0c;他们又是各自主要负责的工作是什么&#xff0c;现在我们心里应该都有数了吧 master 节点&#xff1a; etcd 存储资源配置&#xff0c;ApiServer 提供 RESTful Api 用于交互&#xff0c;scheduler 用于调度 p…

通过将信号频谱与噪声频谱进行比较,自动检测适当的带通滤波器转折频率研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

低代码已经发展到什么水平了

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;生活&#xff08;主要讲一下自己生活相关的内容&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f468;‍&#x1f4bb;上一篇…

simulink学习笔记:基于模型的控制和pid整定

在学习的时候发现了一个很好的学习simulink的网站&#xff0c;打算来练练手&#xff1a;Introduction: Simulink Control&#xff0c;过程中会涉及到搭建动力学模型和设计pid控制器&#xff08;整定pid参数&#xff09;。该模型描述的是火车的两节车厢&#xff0c;对前一节车厢…

迪瑞克斯拉算法 — 优化

在上一篇迪瑞克斯拉算法中将功能实现了出来&#xff0c;完成了图集中从源点出发获取所有可达的点的最短距离的收集。 但在代码中getMinDistanceAndUnSelectNode()方法的实现并不简洁&#xff0c;每次获取minNode时&#xff0c;都需要遍历整个Map&#xff0c;时间复杂度太高。这…

《Zookeeper》源码分析(九)之选举通信网络

在上一篇文章中讲到QuorumCnxManager&#xff0c;它负责zookeeper服务器在选举期间最底层的网络通信&#xff0c;整个网络涉及到的类如下&#xff1a; 整个网络建立的过程如下&#xff1a; 选举前创建好QuorumCnxManager实例&#xff0c;并在QuorumCnxManager构造函数中创建好…

scope组件穿透

今天我们以单选框为例来探究一下样式的穿透问题 1.代码 <template><div class""><el-radio v-model"radio" label"1">备选项</el-radio><el-radio v-model"radio" label"2">备选项</el-r…

glOrtho与gluOrtho2D 的作用

gluOrtho2D 函数设置二维正交裁剪区域。 相当于调用 zNear -1 且 zFar 1 的 glOrtho 。 glOrtho定义二维正交投影矩阵&#xff0c;这个矩阵会把视图&#xff08;摄像机&#xff09;空间的坐标转换到一个裁剪空间&#xff0c;一言以蔽之&#xff1a;glOrtho定义了裁剪空间&…

Netty:DelimiterBasedFrameDecoder分析

说明 io.netty.handler.codec.DelimiterBasedFrameDecoder是ByteToMessageDecoder的一个实现类&#xff0c;用一个或多个分割符拆分接收到的 ByteBuf。这个主要用于解析分隔符在帧的末尾的情况。注意&#xff0c;如果分割符在帧的开头&#xff0c;那么解析出来的帧的长度是0&a…