当前位置: 首页 > news >正文

代码随想录算法训练营第二十二天| 491. 递增子序列、46. 全排列、47. 全排列Ⅱ

今日内容

  • Leetcode. 491 递增子序列
  • Leetcode. 46 全排列
  • Leetcode. 47 全排列Ⅱ

Leetcode. 491 递增子序列

文章链接:代码随想录 (programmercarl.com)

题目链接:491. 非递减子序列 - 力扣(LeetCode)

本题也是一个子集问题,根据题意也知道要去重,提到去重就会不自觉地想到 90. 子集 II - 力扣(LeetCode)中的去重。但在本题中不能使用 Leetcode. 90 这种去重思想,因为这种去重需要对数组进行排序,而本题如果进行排序,会对得到的结果产生影响。

所以本题的去重应该用一个 Set 来记录本层已经使用过的元素。

根据上述内容,可写出代码:

class Solution {List<Integer> elem = new LinkedList<>();List<List<Integer>> result = new LinkedList<>();public List<List<Integer>> findSubsequences(int[] nums) {backtracking(nums, 0);return result;}public void backtracking(int[] nums, int startIndex){if (elem.size() >= 2){result.add(new LinkedList<>(elem));}if (startIndex == nums.length){return;}Set<Integer> used = new HashSet<>(); // 记录已使用元素的Setfor (int i = startIndex; i < nums.length; i++){if (!elem.isEmpty() && nums[i] < elem.get(elem.size() - 1) || used.contains(nums[i])){continue;}used.add(nums[i]);elem.add(nums[i]);backtracking(nums, i + 1);elem.remove(elem.size() - 1);}}
}
  • 时间复杂度:O(n * 2 ^ n)
  • 空间复杂度:O(n)

Leetcode. 46 全排列

文章链接:代码随想录 (programmercarl.com)

题目链接:46. 全排列 - 力扣(LeetCode)

本题是回溯问题中的排列问题, 排列问题和组合问题不同,排列问题返回得结果是有序的,比如{1, 2} {2, 1} 在排列问题中是两个不同的结果。

也正因为结果有序,所以和组合问题、分割问题以及子集问题不同,排列问题每次搜索都要从头开始,所以不需要startIndex指示下一次搜索开始的位置。

虽然排列问题不需要startIndex了,但是它返回的结果是有序的,元素的排列顺序依然需要其他变量进行标识。因此需要使用一个数组来记录每个元素的使用情况

本题中,我们使用一个布尔数组 used 来标识每个元素的使用情况,当本层遍历使用到该元素后,该元素在used数组中的值被赋为 true。在遍历元素时,就可以根据 used 数组中对应索引的值来判断是否被使用,被使用就跳过。

排列问题经过抽象得到的树形结构图如下所示:

根据上述内容,写出如下代码:

class Solution {List<Integer> elem = new LinkedList<>();List<List<Integer>> result = new LinkedList<>();public List<List<Integer>> permute(int[] nums) {boolean[] used = new boolean[nums.length]; // 记录元素的使用情况backtracking(nums, used);return result;}public void backtracking(int[] nums, boolean[] used){if (elem.size() == nums.length){result.add(new LinkedList<>(elem));return;}for (int i = 0; i < nums.length; i++){if (used[i]){continue;} // 若元素已使用过,则跳过该元素elem.add(nums[i]);used[i] = true; // 元素被使用,赋值为truebacktracking(nums, used);used[i] = false; // 回溯elem.remove(elem.size() - 1);  }}
}
  • 时间复杂度:O(n!)
  • 空间复杂度:O(n)

Leetcode. 47 全排列Ⅱ

文章链接:代码随想录 (programmercarl.com)

题目链接:47. 全排列 II - 力扣(LeetCode)

本题可以看作是 Leetcode. 46 + Leetcode. 90 的结合,也就是在全排列问题中加入去重。

代码如下:

class Solution {List<Integer> elem = new LinkedList<>();List<List<Integer>> result = new LinkedList<>();public List<List<Integer>> permuteUnique(int[] nums) {boolean[] used = new boolean[nums.length];Arrays.sort(nums); // 注意一定要排序backtracking(nums, used);return result;}public void backtracking(int[] nums, boolean[] used){if (elem.size() == nums.length){result.add(new LinkedList<>(elem));return;}for (int i = 0; i < nums.length; i++){if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true){ // 判断元素是否被使用以及去重continue;}if (used[i]){continue;}elem.add(nums[i]);used[i] = true;backtracking(nums, used);used[i] = false;elem.remove(elem.size() - 1);}}
}
  • 时间复杂度:O(n! * n)
  • 空间复杂度:O(n)

总结

第一题是去重的不同,去重时注意所给数据是否有序,有序的话就可以使用 Leetcode. 90 的去重思想;无序的话就需要其他容器记录已使用元素。

排列问题要求结果有序,所以每次遍历都需要从头开始,并且需要一个容器记录哪些元素被使用过,注意这里的标识不是为了去重,而是为了调整结果顺序。

去重和判断元素使用情况的区别,从Leetcode. 47 就可以看出来了。

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HTTP1.0 到 HTTP3.0 的优化
  • Linux常用命令合集
  • 免费的 Mac 应用清理工具Pearcleaner v3.8.6
  • 透视表支持自定义聚合公式,新增字体管理功能,DataEase开源BI工具v2.10 LTS版本发布
  • FastAPI 深度指南:使用依赖注入处理分页和过滤逻辑
  • 深度学习的模型知识点介绍和总结
  • Anolis 8 NVME over TCP 配置使用
  • [数据集][目标检测]打电话检测数据集VOC+YOLO格式8985张1类别
  • 数据分析-埋点
  • 【Python报错已解决】No Python at ‘C:Users…Python Python39python.exe’
  • jdbc-day03
  • 1321. 餐館營業額變化增長
  • AtCoder Beginner Contest 370(A~E)
  • php转职golang第二期
  • 新学期学生资料在线收集,老师用它一分钟搞定!
  • 网络传输文件的问题
  • Angular数据绑定机制
  • Create React App 使用
  • ES学习笔记(12)--Symbol
  • FineReport中如何实现自动滚屏效果
  • mac修复ab及siege安装
  • 代理模式
  • 官方解决所有 npm 全局安装权限问题
  • 盘点那些不知名却常用的 Git 操作
  • 七牛云假注销小指南
  • 实现菜单下拉伸展折叠效果demo
  • 硬币翻转问题,区间操作
  • 怎么把视频里的音乐提取出来
  • const的用法,特别是用在函数前面与后面的区别
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • $$$$GB2312-80区位编码表$$$$
  • (30)数组元素和与数字和的绝对差
  • (C#)一个最简单的链表类
  • (C11) 泛型表达式
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (篇九)MySQL常用内置函数
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (转)我也是一只IT小小鸟
  • .“空心村”成因分析及解决对策122344
  • .FileZilla的使用和主动模式被动模式介绍
  • .form文件_SSM框架文件上传篇
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .Net Core 中间件与过滤器
  • .Net Remoting常用部署结构
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】