代码随想录 回溯算法-排序

目录

46.全排序 

47.全排列|| 

332.重新安排行程


46.全排序 

46. 全排列

中等

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

 

 通过全局变量used数组进行树枝去重

class Solution {  
    // 存储所有可能的排列结果的列表  
    List<List<Integer>> result = new ArrayList<>();  
    // 存储当前正在构建的排列的列表  
    List<Integer> path = new ArrayList<>();  
    // 标记数组,用于记录数字是否已经被使用  
    int[] used;  
  
    // 外部接口方法,用于获取数字数组的所有排列  
    public List<List<Integer>> permute(int[] nums) {  
        // 初始化used数组,大小为21,因为题目中暗示了nums中的元素范围为[0, 10],所以偏移10后使用  
        used = new int[nums.length];  
        // 开始回溯过程  
        backtracking(nums);  
        // 返回所有可能的排列结果  
        return result;  
    }  
  
    // 回溯方法,用于生成排列  
    public void backtracking(int[] nums){  
        // 如果当前路径的长度等于nums的长度,说明一个排列已经生成完毕  
        if(path.size() == nums.length){  
            // 将当前路径添加到结果列表中  
            result.add(new ArrayList(path));  
            // 结束当前递归分支  
            return;  
        }  
        // 遍历nums数组中的每个元素  
        for(int i = 0; i < nums.length; i++){  
            // 如果当前元素已经被使用,则跳过  
            if(used[i] == 1){  
                continue;  
            }  
            // 将当前元素添加到路径中  
            path.add(nums[i]);  
            // 标记当前元素为已使用  
            used[i] = 1;  
            // 继续递归生成下一个位置的元素  
            backtracking(nums);  
            // 回溯,撤销选择,标记当前元素为未使用  
            used[i] = 0;  
            // 回溯,撤销选择,从路径中移除当前元素  
            path.removeLast();  
        }  
    }  
}

47.全排列|| 

47. 全排列 II

中等

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

 

这里要用到树枝去重和树层去重,树枝去重使用used数组,和之前的方式一样,树层去重去 

class Solution {  
    // 存储所有可能的排列结果的列表  
    List<List<Integer>> result = new ArrayList<>();  
    // 存储当前正在构建的排列的列表  
    List<Integer> path = new ArrayList<>();  
    // 标记数组,用于记录数字是否已经被使用  
    int[] used;  
  
    // 外部接口方法,用于获取数字数组的所有不重复排列  
    public List<List<Integer>> permuteUnique(int[] nums) {  
        // 初始化used数组,大小为nums的长度  
        used = new int[nums.length];  
        // 对nums数组进行排序,以便在回溯过程中跳过重复元素  
        Arrays.sort(nums);  
        // 开始回溯过程  
        backtracking(nums);  
        // 返回所有可能的排列结果  
        return result;  
    }  
  
    // 回溯方法,用于生成不重复排列  
    public void backtracking(int[] nums){  
        // 如果当前路径的长度等于nums的长度,说明一个排列已经生成完毕  
        if(path.size() == nums.length){  
            // 将当前路径添加到结果列表中  
            result.add(new ArrayList<>(path));  
            // 结束当前递归分支  
            return;  
        }  
        // 遍历nums数组中的每个元素  
        for(int i = 0; i < nums.length; i++){  
            // 如果当前元素和前一个元素相同,并且前一个元素未被使用,则跳过当前元素  
            // 这样可以避免生成包含重复元素的排列  
            if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == 0){  
                continue;  
            }  
            // 如果当前元素已经被使用,则跳过  
            if(used[i] == 1){  
                continue;  
            }  
            // 将当前元素添加到路径中  
            path.add(nums[i]);  
            // 标记当前元素为已使用  
            used[i] = 1;  
            // 继续递归生成下一个位置的元素  
            backtracking(nums);  
            // 回溯,撤销选择,标记当前元素为未使用  
            used[i] = 0;  
            // 回溯,撤销选择,从路径中移除当前元素  
            path.removeLast();  
        }  
    }  
}

332.重新安排行程

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

这里先对传入的集合排序是为了先访问到字典排序更小的元素,backtracking返回boolean是为了只找一个有效行程,先找到的那个有效行程一定是字典排序更小的 ,用used数组来进行树枝去重

class Solution {  
    // 结果列表,存储最终的旅行行程  
    private ArrayList<String> res;  
    // 当前构建的行程路径  
    private ArrayList<String> path = new ArrayList<>();

    //去重
    int[] used;  
  
    // 主方法,用于找到旅行行程  
    public List<String> findItinerary(List<List<String>> tickets) {  
        // 将tickets按照目的地(即第二个元素)进行排序  
        // 这样能够确保回溯时优先选择目的地字母顺序靠前的航班  
        Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1)));  
        // 起点是"JFK"  
        path.add("JFK");  
        // 标记数组,用于记录机票是否已被使用  
        used = new int[tickets.size()];  
        // 开始回溯  
        backTracking(tickets);  
        // 返回最终构建的旅行行程  
        return res;  
    }  
  
    // 回溯方法,用于生成旅行行程  
    public boolean backTracking(List<List<String>> tickets) {  
        // 如果路径中的机场数量等于机票数量加1(因为起点"JFK"也算一个点)  
        // 则说明已经构建了一个完整的旅行行程  
        if (path.size() == tickets.size() + 1) {  
            // 将当前路径赋值给结果列表  
            res = new ArrayList<>(path);  
            // 找到了一个完整的行程,返回true  
            return true;  
        }  
  
        // 遍历所有机票  
        for (int i = 0; i < tickets.size(); i++) {  
            // 如果机票未被使用,且当前机票的起点与当前路径的最后一个机场相同  
            if (used[i] == 0 && tickets.get(i).get(0).equals(path.getLast())) {  
                // 将当前机票的终点添加到路径中  
                path.add(tickets.get(i).get(1));  
                // 标记当前机票为已使用  
                used[i] = 1;  
  
                // 继续回溯,寻找下一个机票  
                if (backTracking(tickets)) {  
                    // 如果找到了一个完整的行程,则直接返回true  
                    return true;  
                }  
  
                // 回溯,撤销选择  
                // 标记当前机票为未使用  
                used[i] = 0;  
                // 从路径中移除当前机票的终点  
                path.removeLast();  
            }  
        }  
  
        // 如果无法构建完整的行程,则返回false  
        return false;  
    }  
}

 

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

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

相关文章

Java零基础 - 数组的定义和声明

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

Git 远程操作

1.分布式版本控制系统 我们目前所说的所有内容&#xff08;工作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地&#xff01;也就是在你的笔记本或者计算机上。而我们的 Git 其实是分布式版本控制系统&#xff01;什么意思呢 可以简单理解为&am…

Windows下PostgreSQL安装教程

一、下载 https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

提醒一下!今年考研的人不要太老实了!!

今年准备计算机考研的同学&#xff0c;别太老实了&#xff01;别人说什么你就信什么 如果你的工作能力不足以支撑找到一个满意的工作&#xff0c;那我建议再沉淀两年&#xff01; 很多同学其实有点眼高手低&#xff0c;在计算机专业&#xff0c;低于1w的工作看不上&#xff0…

论文阅读:Scalable Diffusion Models with Transformers

Scalable Diffusion Models with Transformers 论文链接 介绍 传统的扩散模型基于一个U-Net骨架&#xff0c;这篇文章提出了一种新的扩散模型结构&#xff0c;将U-Net替换为一个transformer&#xff0c;并将这种结构称为Diffusion Transformers (DiTs)。他们还发现&#xff…

【网络】:HTTP服务器

HTTP服务器 一.预备知识二.HTTP的请求和响应三.写一个简单的HTTP服务器四.返回响应五.HTTP方法和状态码 一.预备知识 1.域名 https://www.baidu.com&#xff0c;这是一个域名。在技术角度上&#xff0c;访问一个服务器其实只需要知道它的ip和域名就行了&#xff0c;而域名主要…

电力物联网系统设计

电力物联网系统设计 简介 在新能源行业从业多年&#xff0c;参与和负责过大大小小的的项目&#xff0c;发电侧、电网侧、用户侧系统都有过实际的项目经验&#xff0c;这些项目或多或少都有物联网采集方面的需求&#xff0c;本篇文章将会对电力行业物联网经验做一个总结分享。 …

LeetCode 刷题 [C++] 第3题.无重复字符的最长子串

题目描述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 题目分析 可以使用滑动窗口加哈希表来实现&#xff1a; 使用start和end两个变脸来表示滑动窗口的头部位置和尾部位置&#xff0c;两者开始均为0&#xff1b;借助哈希表来记录已经遍…

六、长短时记忆网络语言模型(LSTM)

为了解决深度神经网络中的梯度消失问题&#xff0c;提出了一种特殊的RNN模型——长短期记忆网络&#xff08;Long Short-Term Memory networks, LSTM&#xff09;&#xff0c;能够有效的传递和表达长时间序列中的信息并且不会导致长时间前的有用信息被忽略。 长短时记忆网络原理…

vue iis 配置

下载安装两个IIS模块 1). 传送门&#xff1a;URL Rewrite 2). 传送门&#xff1a;Application Request Routing 注 : 只有在 服务器的主页 有Application Request Routing 部署VUE网站 生成网站 在VUE项目打包生成出发布文件,即文件夹 dist,此处忽略 复制到你需要存放网站的…

10 事务控制

文章目录 事务控制事务概述事务操作事务四大特性事务隔离级别 事务控制 事务概述 MySQL 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&#xff0c;在人员管理系统中&#xff0c;你删除一个人员&#xff0c;既需要删除人员的基本资料&#xff0c;也要删除和该…

kafka报文模拟工具的使用

日常项目中经常会碰到消费kafka某个topic的数据&#xff0c;如果知道报文格式&#xff0c;即可使用工具去模拟发送报文&#xff0c;以此测试代码中是否能正常消费到这个数据。 工具资源已上传&#xff0c;可直接访问连接下载&#xff1a;https://download.csdn.net/download/w…

Learn OpenGL 02 你好,三角形

图形渲染管线 图形渲染管线的每个阶段的抽象展示。要注意蓝色部分代表的是我们可以注入自定义的着色器的部分 首先&#xff0c;我们以数组的形式传递3个3D坐标作为图形渲染管线的输入&#xff0c;用来表示一个三角形&#xff0c;这个数组叫做顶点数据(Vertex Data)。 顶点着色…

编译内核错误 multiple definition of `yylloc‘

编译内核错误 # make ARCHarm CROSS_COMPILEarm-mix410-linux- uImageHOSTLD scripts/dtc/dtc /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss0x10): multiple definition of yylloc; scripts/dtc/dtc-lexer.lex.o:(.bss0x0): first defined here collect2: error: ld ret…

昏暗场景增强-低照度增强-弱光增强(附代码)

引言 随着现代科技的发展&#xff0c;图像采集设备已经渗透到生活的方方面面&#xff0c;然而在昏暗场景、低照度或弱光条件下&#xff0c;图像的质量往往受到严重影响&#xff0c;表现为亮度不足、对比度低下、色彩失真以及细节丢失等问题。这类图像对于人眼识别和计算机视觉…

FPGA IBUFG

IBUFG和IBUFGDS的输入端仅仅与芯片的专用全局时钟输入管脚有物理连接&#xff0c;与普通IO和其它内部CLB等没有物理连接。 所以&#xff0c;IBUFG输入的不能直接接另外信号。 GTH transceiver primitives are called GTHE3_COMMON and GTHE3_CHANNEL in UltraScale FPGAs, an…

部署LVS+Keepalived高可用群集(抢占模式,非抢占模式,延迟模式)

目录 一、LVSKeepalived高可用群集 1、实验环境 2、 主和备keepalived的配置 2.1 yum安装ipvsadm和keepalived工具 2.2 添加ip_vs模块并开启ipvsadm 2.3 修改keepalived的配置文件 2.4 调整proc响应参数&#xff0c;关闭linux内核的重定向参数响应 2.5 将主服务器的kee…

SpringBoot整合Redis实现分布式锁

SpringBoot整合Redis实现分布式锁 分布式系统为什么要使用分布式锁&#xff1f; 首先&#xff0c;分布式系统是由多个独立节点组成的&#xff0c;这些节点可能运行在不同的物理或虚拟机器上&#xff0c;它们通过网络进行通信和协作。在这样的环境中&#xff0c;多个节点可能同…

群智能优化算法:巨型犰狳优化算法(GAO)求解23个基准函数(提供MATLAB代码)

一、巨型犰狳优化算法 巨型犰狳优化算法&#xff08;Giant Armadillo Optimization&#xff0c;GAO&#xff09;由Omar Alsayyed等人于2023年提出&#xff0c;该算法模仿了巨型犰狳在野外的自然行为。GAO设计的基本灵感来自巨型犰狳向猎物位置移动和挖掘白蚁丘的狩猎策略。GAO…

LLM 构建Data Muti-Agents 赋能数据分析平台的实践之①:数据采集

一、 概述 在推进产业数字化的过程中&#xff0c;数据作为最重要的资源是优化产业管控过程和提升产业数字化水平的基础一环&#xff0c;如何实现数据采集工作的便利化、高效化、智能化是降低数据分析体系运转成本以及推动数据价值挖掘体系的基础手段。随着数字化在产业端的推进…