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

目录

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;  }  
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高效安全数据实时同步ftp文件解决方案

随着企业对于数据的实时同步需求不断攀升&#xff0c;文件传输协议&#xff08;FTP&#xff09;作为一项历史悠久的技术&#xff0c;在企业数据交换、网站内容更新以及远程数据备份等领域扮演了重要角色。然而&#xff0c;随着企业业务的快速扩展&#xff0c;FTP在数据实时同步…

Python爬虫——scrapy-2

目录 scrapy简介 安装ipython 基本使用 访问百度 总结 scrapy简介 scrapy shell是Scrapy框架提供的一个交互式命令行工具&#xff0c;用于快速调试和测试Scrapy爬虫。它能够加载Scrapy项目的设置和爬虫代码&#xff0c;并提供一个交互式环境&#xff0c;可以在其中执行Scra…

简单认识Linux

今天带大家简单认识一下Linux&#xff0c;它和我们日常用的Windows有什么不同呢&#xff1f; Linux介绍 Linux内核&发行版 Linux内核版本 内核(kernel)是系统的心脏&#xff0c;是运行程序和管理像磁盘和打印机等硬件设备的核心程序&#xff0c;它提供了一个在裸设备与…

python从入门到实践答案

python从入门到实践答案 第二章 变量和简单的数类型1. 简单消息2. 多条简单消息3.个性化消息4. 调整名字的大小写5. 名言6. 名言27. 剔除人名中的空白8. 数字8&#xff1a;9 最喜欢的数字&#xff1a;10. 添加注释11. Python之禅&#xff1a; 第三章 列表简介1.姓名2. 继续使用…

Android使用WebView打开外部网页链接

发布Android应用&#xff0c;除了用原生开发外&#xff0c;更多是采用内嵌H5网页的方式来做&#xff0c;便于更新以及多平台使用。 一、第一种方式是直接通过WebView打开外部H5链接。 新建Android工程 直接创建一个工程&#xff0c;点击运行就可以了&#xff0c;打开是个空页…

吴恩达机器学习-可选实验室:特征工程和多项式回归(Feature Engineering and Polynomial Regression)

文章目录 目标工具特征工程和多项式回归概述多项式特征选择功能备用视图扩展功能复杂的功能 恭喜! 目标 在本实验中&#xff0c;你将:探索特征工程和多项式回归&#xff0c;它们允许您使用线性回归的机制来拟合非常复杂&#xff0c;甚至非常非线性的函数。 工具 您将利用在以…

b站小土堆pytorch学习记录—— P27-P29 完整的模型训练套路

文章目录 一、定义模型&#xff08;放在model.py文件中&#xff09;二、训练三、测试四、完整的训练和测试代码 一、定义模型&#xff08;放在model.py文件中&#xff09; import torch from torch import nnclass Guodong(nn.Module):def __init__(self):super(Guodong,self)…

在ubuntu上使用vscode+gcc-arm-none-eabi+openocd工具开发STM32

文章目录 所需工具安装调试搭建过程中遇到的问题 写在前面 老大上周让我用vscode开发STM32&#xff0c;我爽快的答应了&#xff0c;心想大学四年装了这么多环境了这不简简单单&#xff0c;更何况vscode这两年还用过&#xff0c;然而现实总是令人不快的——我竟然花了差不多两周…

BlackHole

BlackHole 文章目录 BlackHole一、关于 BlackHole功能描述 二、安装、卸载安装方式一&#xff1a;下载安装器方式二&#xff1a;使用 Homebrew 安装 卸载方式一&#xff1a;使用卸载器方式二&#xff1a;手动卸载 三、用户使用指南1、Logic Pro X2、GarageBand3、Reaper4、录制…

Material UI 5 学习02-其它按钮组件

Material UI 5 学习02-其它按钮组件 一、IconButton按钮二、 ButtonGroup按钮组1、最基本的实例2、垂直按钮组 一、IconButton按钮 图标按钮通常适用于切换按钮&#xff0c;允许选择或选择单个选项 取消选择&#xff0c;例如在项目中添加或删除星号。 <IconButton aria-lab…

牛客小白月赛88

E.多重映射 解题思路 对集合进行整体操作&#xff0c;集合大小只增不减&#xff0c;问最后集合标号维护集合&#xff0c;考虑并查集但直接用并差集维护会有以下问题&#xff1a;当前集合变标号&#xff0c;可能会和之前标号相同&#xff0c;则进行并查集操作时&#xff0c;会接…

Windows下Node.js安装保姆级教程

一、Node.js 下载 访问Node.js官网&#xff0c;点击下载Node.js 下载完成后即可在下载文件中查看安装包 二、安装 一&#xff09;点击安装包开始安装&#xff0c;进入Weclcome界面点击Next 二&#xff09;勾选同意协议&#xff0c;点击Next 三&#xff09;根据需要选择安装路…