LeetCode算法训练-回溯 491.递增子序列 46.全排列 47.全排列 II
欢迎关注个人公众号:爱喝可可牛奶
LeetCode算法训练-回溯 491.递增子序列 46.全排列 47.全排列 II
LeetCode 491. 递增子序列
分析
找出并返回所有数组中不同的递增子序列
绝对不能先升序 绝对不能先升序 绝对不能先升序 这样会改变原有数组的结构
子序列中元素在数组中不一定相邻
只要叶子节点,也就是path,一满足条件,直接加入res
注意去重used[] 数组只针对当前节点的后序节点 要在回溯函数中定义 画回溯树一看便知
代码
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的元素是升序的
if (path.size() > 1) {
res.add(new LinkedList<>(path));
// 注意这里不要加return,要取树上的节点
}
// 元素值为used数组索引 只对同一行进行去重
int[] used = new int[201];
for (int i = start; i < nums.length; i++) {
// path 为空 当前元素小于path最后一个元素 或者这个元素在本层已经使用过了 跳过这个继续横向遍历
if (!path.isEmpty() && nums[i] < path.getLast() || (used[nums[i] + 100] == 1)) {
// 如果是break 应该是终止当前节点的横向遍历 进入递归
continue;
}
used[nums[i] + 100] = 1;
path.add(nums[i]);
backtracking(nums, i + 1);
path.removeLast();
}
}
}
LeetCode 46. 全排列
分析
全排列,收集回溯树的叶子节点即可 注意终止条件要return
But 因为搜索过程每次都从第一个元素开始,要记录哪些元素已经使用过了 used[]数组应该是全局的
代码
class Solution {
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
boolean[] used;
public List<List<Integer>> permute(int[] nums) {
if (nums.length == 0){
return result;
}
used = new boolean[nums.length];
permuteHelper(nums);
return result;
}
private void permuteHelper(int[] nums){
if (path.size() == nums.length){
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++){
if (used[i]){
continue;
}
used[i] = true;
path.add(nums[i]);
permuteHelper(nums);
path.removeLast();
used[i] = false;
}
}
}
LeetCode 47. 全排列 II
分析
按任意顺序 返回所有不重复的全排列
涉及到如何去重 根据用例画一个回溯树看看
在横向遍历时,如果当前元素==前一个元素,continue;
难点:如何判断统一树层当前节点的前一个节点使用过 去看一下当前节点前一个节点的状态
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
代码
class Solution {
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
public List<List<Integer>> permuteUnique(int[] nums) {
if (nums.length == 0){
return result;
}
// 得先排个序才能保证前后元素比较的正确性
Arrays.sort(nums);
boolean[] used = new boolean[nums.length];
permuteHelper(nums,used);
return result;
}
private void permuteHelper(int[] nums, boolean[] used){
if (path.size() == nums.length){
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++){
// 一定要通过used保证nums[i-1]是树层上nums[i]的前一个元素
if(i > 0 && nums[i] == nums[i-1] && !used[i-1]){
continue;
}
if (!used[i]){
used[i] = true;
path.add(nums[i]);
permuteHelper(nums,used);
path.removeLast();
used[i] = false;
}
}
}
}
总结
- 组合问题和排列问题是在树形结构的叶子节点上收集结果,而子集问题就是取树上所有节点的结果
- 理清回溯树树层、树枝的节点关系 for循环处理的是树层,递归调用函数处理的是树枝
- 如果没有startIndex来确定取的是数组中哪一个元素,used[]数组+for循环能间接确定这个元素是不是取过
LeetCode算法训练-回溯 491.递增子序列 46.全排列 47.全排列 II的更多相关文章
- Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences)
Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences) 深度优先搜索的解题详细介绍,点击 给定一个整型数组, 你的任务是找到所有该数组 ...
- Java实现 LeetCode 491递增子序列
491. 递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2. 示例: 输入: [4, 6, 7, 7] 输出: [[4, 6], [4, 7], [4, ...
- Leetcode 491.递增子序列
递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2. 示例: 输入: [4, 6, 7, 7] 输出: [[4, 6], [4, 7], [4, 6, 7] ...
- LeetCode编程训练 - 回溯(Backtracking)
回溯基础 先看一个使用回溯方法求集合子集的例子(78. Subsets),以下代码基本说明了回溯使用的基本框架: //78. Subsets class Solution { private: voi ...
- 算法实践--最长递增子序列(Longest Increasing Subsquence)
什么是最长递增子序列(Longest Increasing Subsquence) 对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5 ...
- 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))
算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...
- 每日一题 LeetCode 491. 递增子序列 【递推】【递增子序列】【动态规划】
题目链接 https://leetcode-cn.com/problems/increasing-subsequences/ 题目说明 题解 主要方法:递推:动态规划 解释说明: 数据表示:观察数据范 ...
- 31. Next Permutation + 46. Permutations + 47. Permutations II + 60. Permutation Sequence
▶ 问题:字典序生成有关的问题. ▶ 31. 由当前序列生成字典序里的下一个序列. ● 初版代码,19 ms class Solution { public: void nextPermutation ...
- 2019年7-8月Leetcode每日训练日志
2019-08-29 #274 H指数 2019-08-28 #287 寻找重复数 #875 爱吃香蕉的珂珂 #704 二分查找 2019-08-27 #744 寻找比目标字母大的最小字母 #225 ...
- Luogu 3402 最长公共子序列(二分,最长递增子序列)
Luogu 3402 最长公共子序列(二分,最长递增子序列) Description 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: ...
随机推荐
- 【CDH数仓】Day02:业务数仓搭建、Kerberos安全认证+Sentry权限管理、集群性能测试及资源管理、邮件报警、数据备份、节点添加删除、CDH的卸载
五.业务数仓搭建 1.业务数据生成 建库建表gmall 需求:生成日期2019年2月10日数据.订单1000个.用户200个.商品sku300个.删除原始数据. CALL init_data('201 ...
- 大规模爬取(新浪为例子)网页之downloader、parser的封装(涉及编码等细节)
import requests import cchardet import traceback from lxml import etree def downloader(url,timeout = ...
- .net做一个基于ChatGpt的微信机器人吧~[全教程]
最近这个ChatGPT很火啊,看了B站上很多视频,自己非常手痒,高低自己得整一个啊,很多人都是把ChatGPT和微信结合在一起,正巧我是Wechaty框架的.net sdk贡献者,这不是一应俱全了吗? ...
- 微信小程序地区和location_id对应关系
点击查看代码 location_list = [ {'location_id': '101010100', 'location_name': ['北京', '北京', '北京']}, {'locati ...
- .Net 7 团队把国内的龙芯确实当做一等公民和弃用的项目
楔子: 国内龙芯据说是用的自己的指令集,在研究ILC的时候,发现了龙芯在微软那边确实是一等公民的存在. 龙芯官网 龙芯平台.NET,是龙芯公司基于开源社区.NET独立研发适配的龙芯版本,我们会长期进行 ...
- React中实现keepalive组件缓存效果
背景:由于react官方并没有提供缓存组件相关的api(类似vue中的keepalive),在某些场景,会使得页面交互性变的很差,比如在有搜索条件的表格页面,点击某一条数据跳转到详情页面,再返回表格页 ...
- 刷题笔记——2181.信息学奥赛一本通T1005-地球人口承载力估计
题目 2181.信息学奥赛一本通T1005-地球人口承载力估计 2999.牛吃牧草 代码 x, a, y, b = map(int,input().strip().split()) z = float ...
- (19)go-micro微服务filebeat收集日志
目录 一 Filebeat介绍 二 FileBeat基本组成 三 FileBeat工作原理 四 Filebeat如何记录文件状态: 五 Filebeat如何保证事件至少被输出一次 六 安装Filebe ...
- 动力节点—day05
数组 Java语言当中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是Object 数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据集合),多个数据元素的类型必须是一致的 数组当中 ...
- MySQL优化六,锁
一,MySQL中的锁 InnoDB中锁非常多,总的来说,可以如下分类: 这些锁都是做什么的?具体含义是什么?我们现在来一一学习. 1.2,解决并发事务问题 我们已经知道事务并发执行时可能带来的各种问题 ...