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

数据结构刷题(二十二):90子集II、491递增子序列、46全排列

1.子集II

题目链接

思路:这是一道标准的组合问题+数组排序+去重。依然是使用回溯。

注意:去重代码只需要判断同一树层上是否有重复,同组合总和II(https://blog.csdn.net/xiaomingming99/article/details/129396344

解法:

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> subsetsWithDup(int[] nums) {// 记得数组排序Arrays.sort(nums);back(nums, 0);return res;}private void back(int[] nums, int startIndex) {res.add(new ArrayList<>(path));for (int i = startIndex; i < nums.length; i++){// 去重if (i > startIndex && nums[i] == nums[i - 1])continue;path.add(nums[i]);back(nums, i + 1);path.removeLast();  // 回溯}}
}

2.递增子序列

题目链接

思路:回溯+数组去重;

回溯三部曲:

  • 返回参数:startindex和数组nums。 全局变量path(记录单个结果)和res(记录结果集合)

  • 终止条件:本题要求递增子序列大小至少为2,所以要判断path.size()>=2

  • 单层逻辑:for循环中,需要判断path的最后一个元素是否大于当前nums[i],且还需要添加代码实现同一父节点下的同层上使用过的元素就不能再使用

注意:

1.&&和||同时出现时,&&优先级更高,先执行&&

2.在90.子集II (opens new window)中是通过排序原数组,判断同一树层元素是否重复来达到去重。

而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。

class Solution {private  LinkedList<Integer> path = new LinkedList<>();private  List<List<Integer>> res = new ArrayList<>();public List<List<Integer>> findSubsequences(int[] nums) {backtracking(nums,0);return res;}private void backtracking (int[] nums, int start) {// path的size必须大于等于2  且不需要return,因为后面可能还有更长的符合条件的序列if (path.size() >= 2) {res.add(new ArrayList<>(path));}// 标记数组  用于去重  // 比如[4,6,7,7] 使用这个数组就可以只出现一次[4,6,7] 标记6使用过int[] used = new int[201];for (int i = start; i < nums.length; i++) {// 先执行&&,判断path的最后一个元素是否大于当前值,如果是则说明不符合递增// 后执行|| 判断当前元素是否被使用过if (!path.isEmpty() && nums[i] < path.getLast()  ||(used[nums[i] + 100] == 1)) continue;used[nums[i] + 100] = 1; // 记录这个元素在本层用过了,本层后面不能再用了path.add(nums[i]);backtracking(nums, i + 1);path.removeLast();}}
}

3.全排列

题目链接

思路:回溯的排列问题。

回溯三部曲:

  • 递归函数参数:参数只需要nums。不需要startIndex参数,因为排列问题,每次都要从头开始搜索。全局变量path(记录单个结果)和res(记录结果集合)

  • 递归终止条件:只需要收集元素的数组path大小达到和nums数组一样大,说明到达叶子结点,可以返回

  • 单层搜索的逻辑:for循环中需要判断当前元素是否已经在path中,若在直接continue。

注意: 首先排列是有序的,也就是说 [1,2] 和 [2,1] 是两个集合,区别于组合问题。

解法:

class Solution {List<List<Integer>> res = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> permute(int[] nums) {back(nums);return res;}private void back(int[] nums) {// 终止条件if (path.size() == nums.length){res.add(new ArrayList<>(path));return;}for (int i = 0; i < nums.length; i++){// 判断path中是否含有遍历元素if (path.contains(nums[i]))continue;path.add(nums[i]);back(nums);path.removeLast();}}
}
http://www.lryc.cn/news/37416.html

相关文章:

  • AI+人类,实现高效网络安全
  • 牛客小白月赛68【A-E】
  • WIFI P2P架构
  • 架构师之中台思维_系统发展之路_结果和抽象之间平衡的艺术
  • 23届非科班选手秋招转码指南
  • 《传感器技术》考试学习笔记
  • 第十五章 opengl之高级OpenGL(模板测试)
  • 【C语言蓝桥杯每日一题】—— 单词分析
  • Web2:Tomcat
  • C++语法规则2(C++面向对象)
  • 第八批国家药品集中采购-(附药品集采目录明细下载)
  • 政府工作报告连提9年科技创新 企业研发如何“又快又好”
  • GM8773C 是一款 1:2 DSI 桥接芯片,可实现 4 路进 8 路出转换器功能、视频分离器功能。
  • Java常用包名和说明
  • dva01-初识
  • 信捷 XDH Ethercat A_WRITE指令
  • Spring Cloud ( Eureka集群的搭建 )
  • Python re 模块
  • 为什么越来越多的人开始学习大数据
  • 【C++】C++核心编程(二)---引用
  • 原型设计模式
  • JVM结构-类加载(类加载子系统,类加载的角色,类加载的过程,类加载器分类,双亲委派机制,类的主/被动使用)
  • vcpkg私有port的创建和使用
  • LeetCode——203. 移除链表元素
  • [Java Web]Request对象 | 超1w字带你熟悉Servlet中的request请求
  • 求一个补码表示数的原始值的三种方式
  • 【计算机组成原理】
  • 论文分享:图像识别与隐私安全
  • 计算机基础小结
  • Linux服务器还有漏洞?建议使用 OpenVAS 日常检查!