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

代码随想录算法训练营第21天 -- 回溯4 || 491.非递减子序列 / 46.全排列 /47.全排列 II

代码随想录算法训练营第21天 -- 回溯4 || 491.非递减子序列 / 46.全排列 /47.全排列 II

  • 491.非递减子序列
    • 解题思路
  • 46.全排列
    • 解题思路
  • 47.全排列II
    • 解题思路
    • 去重细节

491.非递减子序列

解题思路

首先这道题默认不能对数组进行排序,先自己画一下树状图:
在这里插入图片描述
本题设计到树层去重。
对于子集问题,无递归终止条件。
对于本题,当数组元素个数大于等于2时,才可以,这是其中一个条件;
其次,集合第一个元素要大于等于子序列的最后一个元素;
对于树层去重,对于本题不能使用used数组,因为本题的序列不是单调的,相同的数可能不挨在一起,但我们依然要做树层去重,这里我们使用哈希 unordered_set 进行去重,并且我们让其在 for 循环外面,保证每次递归都重新定义一个哈希 set,这样回溯我们就不用对 set 进行 pop 操作了。

完整代码如下:

class Solution {
public:vector<int> path;vector<vector<int>> res;void backtracking(vector<int>& nums, int startindex) {if (path.size() > 1) res.push_back(path);unordered_set<int> uset;for (int i = startindex; i < nums.size(); i ++) {if (!path.empty() && nums[i] < path.back() || uset.find(nums[i]) != uset.end())continue;uset.insert(nums[i]);path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}vector<vector<int>> findSubsequences(vector<int>& nums) {backtracking(nums, 0);return res;}
};

我解释一下 if 里的条件:
首先我们得两个条件:nums[i] < path.back()uset已经有这个元素,这两个元素成立一个就 continue 操作;但对于第一个条件,我们需要保证 path 数组非空,所以加了一个非空判断。

46.全排列

解题思路

本题进入排列专题。
排列问题不需要startindex参数,因为当取第二个数的时候,树枝还可以再取第一个数,只是顺序不同而已。
排列问题需要利用used数组,用来记录哪个位置的数取过,哪个位置的数没取过。
排列问题纵向遍历的深度由数组大小决定。
在这里插入图片描述

完整代码:

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

47.全排列II

解题思路

在这里插入图片描述

本题和上一题的区别就在于本题需要去重,对于去重操作,无非就是多了两行代码操作,对树层进行去重:

	if (i && nums[i] == nums[i - 1] && used[i - 1] == false) continue;

除此之外,本题还需要先对数组进行排序,然后再进行上一题和去重的操作

完整代码如下:

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

去重细节

本题其实,树枝去重和树层去重都可以,下面以 [1, 1, 1] 为例,画出树层去重和树枝去重的两个树状图。

树层去重:
在这里插入图片描述

树枝去重:
在这里插入图片描述

所以,在去重操作的代码中,false 也可以写成 true

	if (i && nums[i] == nums[i - 1] && used[i - 1] == true)continue;

上述代码也是正确的。

但是,一般树枝去重的效率不如树层去重,我们会优先选择树层去重。

http://www.dtcms.com/a/407869.html

相关文章:

  • 绍兴公司网站建设 中企动力绍兴wordpress edc
  • 怎么找到做网站的客户岳阳网站建设团队
  • Android匿名共享内存突破Binder传递大小限制
  • 网络网站推广首荐乐云seowordpress关键字内链
  • 元气森林宇宙大赛——第五届高校创新挑战赛
  • 51的烧录与调试
  • 如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘tokenizers’ 问题
  • 数字门店的未来蓝图:从水果店到餐厅再到超市
  • 做动态图片下载哪个网站好百度高级搜索网址
  • Mnn模型转换
  • 在Windows中通过网络共享文件
  • 网站开发入门习题优化大师兑换码
  • 保定网站制作方案四川住房和城乡建设厅进不去网站
  • SPA 路由 fallback 机制 + 304状态码 + 示例
  • 网站怎么设置标题给我一个可以在线观看片
  • Linux学习记录--利用信号量来调度共享资源(2)
  • 管理一个网站的后台怎么做做app要多少钱
  • 自动化测试篇--用例篇
  • 贵阳网络公司网站建设衣服网站模板
  • 基于MATLAB的Copula函数实现示例
  • 攻防世界-Web-simple_js
  • 【Triton 教程】triton_language.ravel
  • 微信网站建设需要那些资料嵌入式软件开发项目
  • 中建一局华江建设有限公司网站类似于wordpress的
  • 学生个人网页设计作品模板肇庆网站快速排名优化
  • 网站优化的核心不包括wordpress商城小程序
  • 整体设计 完整的逻辑链条之11 三转法论驱动的 ISO - 认知融合逻辑系统:从架构映射到自动化缝合的完整设计
  • 网站服务费怎么做分录查网站
  • 项目发布部署
  • 告别字符串拼接繁琐!Java String.format () 实用指南