Leecode 491. 非递减子序列

题目描述

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

  • 示例 1:

输入:nums = [4,6,7,7]

输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

  • 示例 2:

输入:nums = [4,4,3,2,1]

输出:[[4,4]]

解题思路与代码

本题和之前的有重复元素的子集那道题的回溯有点相似,都是其中会有一些重复的元素,而有重复的元素就要涉及到去重的操作。在那道子集的题目中,去重是通过先对集合中元素进行排序,随后再在回溯中使用start变量的条件判断来进行去重。但本题不同的点在于,要求输出的是原序列中非递减的一部分子序列,这意味着我们需要保持原本的排序关系,不能再先对原本序列进行排序操作。从而也就无法用之前那样的方式来进行去重了。本题去重考虑使用unordered_set容器来记录每一层中的变量是否已经在回溯递归中使用过。可以写出如下代码:

class Solution {
public:
vector<vector<int>> result;
vector<int> curVec; void backTracking(const vector<int>& nums, int start){
if(curVec.size() >= 2){ // 只要长度大于等于2的子序列都进行存储
result.push_back(curVec);
}
unordered_set<int> used; // 用于记录已经用过的元素
for(int i = start; i < nums.size(); i++){
if(!curVec.empty() && nums[i] < curVec.back()) continue; // 如果当前元素比子序列中最后一个元素小,则跳过
if(used.find(nums[i]) != used.end()) continue; // 如果子序列中已经用过当前元素,则跳过
curVec.push_back(nums[i]);
used.insert(nums[i]);
backTracking(nums, i + 1);
curVec.pop_back();
}
} vector<vector<int>> findSubsequences(vector<int>& nums) {
backTracking(nums, 0);
return result;
}
};

Leecode 46. 全排列

题目描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

  • 示例 1:

输入:nums = [1,2,3]

输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

  • 示例 2:

输入:nums = [0,1]

输出:[[0,1],[1,0]]

  • 示例 3:

输入:nums = [1]

输出:[[1]]

解题思路与代码展示

本题要求的是数组中数字的全排列,排列与之前做过的组合的区别在于排列需要关注每个元素出现的顺序,而组合中只需要关注出现了哪些元素。既然是全排列,那么使用回溯法过程中,进行存放结果的条件判断应该非常简单,只需要当前数组中的元素个数等于原数组中的个数即可。但关键在于我们需要如何判断回溯过程中,每一个元素是否已经出现在过当前数组里。因此我们考虑使用一个存放布尔类型的vector来存放某个元素是否被使用过。由此我们可以写出下面代码:

class Solution {
public:
vector<vector<int>> result;
vector<int> curVec; void backTracking(vector<int>& nums, vector<bool> used){
if(curVec.size() == nums.size()){ // 当前数组中的元素数量和原数组元素数量相等,则存放结果
result.push_back(curVec);
return;
}
for(int i = 0; i < nums.size(); i++){
if(used[i]) continue; // 如果当前数已经用过,则直接跳过
curVec.push_back(nums[i]); // 没用过,则将其放到当前数组中
used[i] = true; // 更新used向量
backTracking(nums, used); // 递归
used[i] = false; // 回溯
curVec.pop_back(); // 回溯
}
} vector<vector<int>> permute(vector<int>& nums) {
result.clear();
curVec.clear();
vector<bool> used(nums.size(), false); // 使用used向量来存放每个元素是否有被使用过
backTracking(nums, used);
return result;
}
};

47. 全排列 II

题目描述

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

  • 示例 1:

输入:nums = [1,1,2]

输出:

[[1,1,2],
[1,2,1],
[2,1,1]]
  • 示例 2:

输入:nums = [1,2,3]

输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

解题思路与代码展示

本题与上一题比较相似,区别在于原始数组中可能出现重复元素。如果使用上面的代码会产生重复。为了去重可以考虑使用set来存放结果,并在最后将set转换为vector即可。

class Solution {
public:
set<vector<int>> result; // 使用set来存放结果
vector<int> curVec; void backTrack(vector<int>& nums, vector<bool> used){
if(curVec.size() == nums.size()){
result.insert(curVec);
return;
}
for(int i = 0; i < nums.size(); i++){
if(used[i]) continue;
used[i] = true;
curVec.push_back(nums[i]);
backTrack(nums, used);
curVec.pop_back();
used[i] = false;
}
} vector<vector<int>> permuteUnique(vector<int>& nums) {
result.clear();
curVec.clear();
vector<bool> used(nums.size(), false);
backTrack(nums, used);
vector<vector<int>> re(result.begin(), result.end()); // 将set转换为vector
return re;
}
};

上面代码中的逻辑和上题几乎完全一致,区别仅在于使用了set容器来进行去重。

代码随想录第二十五天 | Leecode 491. 非递减子序列、46. 全排列、47. 全排列 II的更多相关文章

  1. NeHe OpenGL教程 第二十五课:变形

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. Gradle 1.12用户指南翻译——第二十五章. Scala 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  3. centos lamp/lnmp阶段复习 以后搬迁discuz论坛不需要重新安装,只需修改配置文件即可 安装wordpress 安装phpmyadmin 定时备份mysql两种方法 第二十五节课

    centos  lamp/lnmp阶段复习 以后搬迁discuz论坛不需要重新安装,只需修改配置文件即可 安装wordpress  安装phpmyadmin  定时备份mysql两种方法  第二十五节 ...

  4. javaSE第二十五天

    第二十五天    399 1:如何让Netbeans的东西Eclipse能访问.    399 2:GUI(了解)    399 (1)用户图形界面    399 (2)两个包:    399 (3) ...

  5. SQL注入之Sqli-labs系列第二十五关(过滤 OR & AND)和第二十五A关(过滤逻辑运算符注释符)

    开始挑战第二十五关(Trick with OR & AND) 第二十五关A(Trick with comments) 0x1先查看源码 (1)这里的or和and采用了i正则匹配,大小写都无法绕 ...

  6. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. “全栈2019”Java第二十五章:流程控制语句中循环语句while

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. 孤荷凌寒自学python第二十五天初识python的time模块

    孤荷凌寒自学python第二十五天python的time模块 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 通过对time模块添加引用,就可以使用python的time模块来进行相关的时间操 ...

  9. x264代码剖析(十五):核心算法之宏块编码中的变换编码

    x264代码剖析(十五):核心算法之宏块编码中的变换编码 为了进一步节省图像的传输码率.须要对图像进行压缩,通常採用变换编码及量化来消除图像中的相关性以降低图像编码的动态范围.本文主要介绍变换编码的相 ...

  10. 风炫安全WEB安全学习第二十五节课 利用XSS键盘记录

    风炫安全WEB安全学习第二十五节课 利用XSS键盘记录 XSS键盘记录 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源.所以xyz.com下的js脚本采用a ...

随机推荐

  1. linux安装spark

    1.首先在官网下载http://spark.apache.org/downloads.html, 选择与hadoop对应的版本,对应关系为:spark1.6.2--scala2.10:spark2.0 ...

  2. 开源一款串口舵机驱动扩展板-FreakStudio多米诺系列

    原文链接: FreakStudio的博客 摘要 总线舵机扩展板通过UART接口控制多个舵机,支持堆叠级联,最多连接4个扩展板.具备小尺寸设计.供电保护.全双工转半双工通信.稳定供电等特点,适用于多舵机 ...

  3. NetPad:一个.NET开源、跨平台的C#编辑器

    前言 今天大姚给大家分享一个基于.NET开源.跨平台的C#编辑器和游乐场:NetPad. 项目介绍 NetPad是一个基于.NET开源(MIT License).跨平台的C#编辑器和游乐场,它允许用户 ...

  4. MySQL - 数据更新场景

    Excel文件数据更新到表A的某两个字段 Excel文件中Sheet1页有两列,一列是序号,另一列是手机号.表A中有对应的序号列和手机号列. 1.首先,使用Navicat将Excel数据导入数据库,注 ...

  5. 洛谷P10112 [GESP202312 八级] 奖品分配 题解

    题目传送门. 看了题解才发现我有多蠢. 我的做法真是唐完了. 在此之前请学习扩展欧几里得定理和扩展欧几里得定理求逆元. 发现奖品要么 \(N\) 个,要么 \(N+1\) 个,于是分类讨论,当奖品只有 ...

  6. 读论文-新闻推荐系统:近期进展、挑战与机遇的评述(News recommender system_ a review of recent progress, challenges, and opportunities)

    前言 今天读的论文为一篇于2022年发表在"人工智能评论"(Artificial Intelligence Review)的论文,文章主要强调了NRS面临的主要挑战,并从现有技术中 ...

  7. 少样本学习实战:Few-Shot Prompt设计

    让AI用最少样本学会"举一反三" 想象一下,你要教一个外星人认识地球上的动物.如果只给它看三张哈士奇的照片,它可能会认为所有四条腿的动物都叫"哈士奇".这就是A ...

  8. html5文本标签

    标题文本 h1.h2.h3.h4.h5.h6 其中 h1.h2.h3是比较常用的.h3.h4.h5.h6相对来说用的会少一点,除非结构层次比较深才会使用. 段落文本 p <p>这是一个段落 ...

  9. github520cli解决无法github访问问题

    github并没有被GFW直接墙掉,而是因为DNS污染导致经常无法访问 访问的时候经常出现push或者pull代码的时间很长,出现无法访问仓库,请检查是否有权限的报错,这可能就是被DNS污染了 如何解 ...

  10. 【Bug记录】uniapp开发时pages.json和manifest.json注释报错解决方案

    pages.json和manifest.json注释报错问题解决 增强 pages.json和 manifest.json 开发体验 json文件写注释 用 VsCode 开发 uni-app 项目时 ...