算法刷题Day 29 递增子序列+全排列+全排列II

news/2024/11/8 9:10:26/

Day 29 回溯算法

491. 递增子序列

如果直接像下面这样写的话,会出错,出错的案例类似:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9nrEEc2S-1688623883770)(LC491-递增子序列+LC.assets/image-20230703201315163.png)]

class Solution {vector<vector<int>> rst;vector<int> path;void backtracking(const vector<int> &nums, int idx){if (path.size() > 1){rst.push_back(path);}for (int i = idx; i < nums.size(); i++){if (i > idx && nums[i] == nums[i - 1]) // 不能使用这一去重逻辑{continue;}if (path.empty() || path.back() <= nums[i]){path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}}public:vector<vector<int>> findSubsequences(vector<int>& nums) {rst.clear();path.clear();backtracking(nums, 0);return rst;}
};

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

所以不能使用之前的去重逻辑!

同一父节点下的同层上使用过的元素就不能再使用了

正确的写法如下:

class Solution {vector<vector<int>> rst;vector<int> path;void backtracking(const vector<int> &nums, int idx){if (path.size() > 1){rst.push_back(path);}int used[201] = {0};for (int i = idx; i < nums.size(); i++){if ((!path.empty() && path.back() > nums[i]) || used[nums[i] + 100]){continue;}used[nums[i] + 100] = 1;path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}public:vector<vector<int>> findSubsequences(vector<int>& nums) {rst.clear();path.clear();backtracking(nums, 0);return rst;}
};

46. 全排列

需要有一个used数组来记录已经被使用过的元素索引

class Solution {vector<vector<int>> rst;vector<int> path;void backtracking(const vector<int> &nums, vector<bool> &used) {if (path.size() == nums.size()){rst.push_back(path);return;}for (int i = 0; i < nums.size(); ++i){if (used[i]) continue;used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}public:vector<vector<int>> permute(vector<int>& nums) {rst.clear();path.clear();vector<bool> used(nums.size(), false);backtracking(nums, used);return rst;}
};

47. 全排列II

还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了

class Solution {vector<vector<int>> rst;vector<int> path;void backtracking(const vector<int> &nums, vector<bool> &used){if (path.size() == nums.size()){rst.push_back(path);return;}for (int i = 0; i < nums.size(); ++i){if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){continue;}if (!used[i]){used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}}public:vector<vector<int>> permuteUnique(vector<int>& nums) {rst.clear();path.clear();sort(nums.begin(), nums.end());vector<bool> used(nums.size(), false);backtracking(nums, used);return rst;}
};

http://www.ppmy.cn/news/786762.html

相关文章

教你用手机模拟加密门禁卡-不用电脑,不ROOT手机

目标&#xff1a;将门禁卡、考勤卡、会员卡、停车卡、电梯卡等等各种卡模拟进手机里&#xff0c;模拟后可用手机代替刷卡&#xff0c;无需root&#xff0c;不用电脑 ## 背景介绍&#xff1a;1、前言  目前&#xff0c;IC卡已被广泛应用于身份识别、金融消费、安全认证等领域。…

android 判断有无sim卡,Android判断手机里是否有SIM卡

由于项目的需要&#xff0c;要判断手机里是否有sim卡。在网上找了一下资料结果发现&#xff0c;网上的资料很多都是一样的&#xff0c;都是判断sim卡的状态&#xff0c;把代码添加进去后发现不能满足需求。然后就自己看了一下文档。代码如下。 /** * author CX- * 判断 是否含有…

小米NFC手机复制加密IC门禁卡

几年没有发过任何文字信息了。闲来无事发一个NFC手机复制加密门禁卡的教程 思路: 第一步通过破解加密的门禁卡得到dump文件,获取卡号。修改dump文件只保留0扇区0块的内容也就是卡号,通过读卡器写入一张卡空白卡。这时就得到了一张未加密的白卡了。手机NFC可以模拟这张未加密…

Android手机无法识别SD卡的处理方法

1. 首先将SD卡放到读卡器中2. 使用Windows磁盘检查工具检查&#xff0c;选择“自动修复文件系统错误”&#xff0c;如果检查出有错误&#xff0c;再查一遍&#xff0c;直到提示“您的磁盘没有问题”。注&#xff1a;磁盘检查工具位置&#xff1a;SD卡的盘符上右键>属性>工…

连接手机、PC后,SD卡文件不显示怎么解决?

文章来源&#xff1a;https://www.reneelab.com.cn/sd-card-files-not-showing.html 目录 一、SD卡上文件不显示的原因二、如何恢复SD卡中丢失的数据三、SD卡修复方法的详细介绍1、检查SD卡的系统文件错误2、格式化SD卡3、使用Chkdsk修复损坏的SD卡 一、SD卡上文件不显示的原因…

[工业互联-15]:Linux操作与实时Linux操作系统RT Linux( PREEMPT-RT、Xenomai)

目录 第1章 Linux操作系统 1.1 什么是Linux操作系统 1.2 Linux操作系统架构 1.3 常见Linux操作系统发行版本 第2章 实时Linux操作系统 2.1 实时性要求 2.2 实时性实现技术的基本思想 2.2 常见发行版方案 2.3 Xenomai和PREEMPT-RT比较 第3章 PREEMPT-RT 3.1 概述 3…

计算机无法读取手机内存,为什么手机内存卡读取不了?

手机内存卡几乎每天都得使用&#xff0c;使用率非常高&#xff0c;当然出错或出毛病的时间也会很多。如果遇到内存卡读不出来了&#xff0c;该怎么办?接下来&#xff0c;小编就向大家介绍手机内存卡读取不了的解决方案。 1、 手机卡坏掉或者接触不良造成手机内存卡读不出来。如…

解决手机不读卡的几种方法

1、首先确定您的卡是G网的SIM卡还是C网的UIM卡&#xff0c;是否和你的手机支持的网络相匹配。有的用户将C网的U卡插到G网的手机里面&#xff0c;肯定读不出的。 2、如果卡没选错&#xff0c;就用橡皮擦擦拭一下手机卡的金属片&#xff0c;同时用无水酒精擦拭一下手机电池仓内的…