代码随想录||day25 非递减子序列,全排列问题

news2024/11/25 16:42:23

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]]

代码:
用哈希表

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex) {
        if (path.size() > 1) {
            result.push_back(path);
        }
        int used[201] = {0}; // 这里使用数组来进行去重操作,题目说数值范围[-100, 100]
        for (int i = startIndex; i < nums.size(); i++) {
            if ((!path.empty() && nums[i] < path.back())
                    || used[nums[i] + 100] == 1) {
                    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) {
        result.clear();
        path.clear();
        backtracking(nums, 0);
        return result;
    }
};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

不用哈希表,用set

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex) {
        if (path.size() > 1) {
            result.push_back(path);
            // 注意这里不要加return,要取树上的节点
        }
        unordered_set<int> uset; // 使用set对本层元素进行去重
        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();
        }
    }
public:
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        result.clear();
        path.clear();
        backtracking(nums, 0);
        return result;
    }
};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

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]]

代码:

class Solution {  
public:  
    // 存储所有不重复的全排列结果  
    vector<vector<int>> result;  
    // 当前构建的全排列路径  
    vector<int> path;              
    
    // 回溯函数  
    void backtracking(vector<int> nums, vector<bool> &used) {  
        // 基本情况:当路径的长度与 nums 的长度相等时,说明现有排列已完整  
        if (path.size() == nums.size()) {  
            result.push_back(path);  // 将当前排列加入结果集中  
            return;                  // 结束当前递归  
        }  
        
        // 遍历所有元素,用于构建全排列  
        for (int i = 0; i < nums.size(); i++) {  
            // 如果当前元素未被使用  
            if (used[i] == false) {  
                used[i] = true;            // 标记当前元素为已使用  
                path.push_back(nums[i]);   // 将当前元素加入路径  
                
                // 递归调用回溯函数,继续构建下一个元素  
                backtracking(nums, used);   
                
                // 回溯:撤销选择,恢复状态  
                path.pop_back();            // 从路径中移除当前元素  
                used[i] = false;            // 将当前元素标记为未使用  
            }         
        }  
    }  
    
    // 主函数,接收输入并返回所有不重复的全排列  
    vector<vector<int>> permute(vector<int>& nums) {  
        result.clear();                // 清空结果集  
        path.clear();                  // 清空当前路径  
        vector<bool> used(nums.size(), false); // 初始化使用标记数组,初始时都未使用  
        backtracking(nums, used);      // 调用回溯函数开始生成全排列  
        return result;                 // 返回生成的所有不重复全排列  
    }  
};  
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

47全排列||

题目题目链接

题目描述:

给定一个可包含重复数字的序列 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]]
class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking (vector<int>& nums, vector<bool>& used) {
        // 此时说明找到了一组
        if (path.size() == nums.size()) {
            result.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            // used[i - 1] == true,说明同一树枝nums[i - 1]使用过
            // used[i - 1] == false,说明同一树层nums[i - 1]使用过
            // 如果同一树层nums[i - 1]使用过则直接跳过
            if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
                continue;
            }
            if (used[i] == false) {
                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) {
        result.clear();
        path.clear();
        sort(nums.begin(), nums.end()); // 排序
        vector<bool> used(nums.size(), false);
        backtracking(nums, used);
        return result;
    }
};
  1. 去重的核心逻辑:

    • 这里的去重逻辑比较巧妙:
       

      if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { continue; }

      • i > 0:确保不是第一个元素。
      • nums[i] == nums[i - 1]:检查当前元素和前一个元素是否相同(即为重复)。
      • used[i - 1] == false:确保只有在前一个相同元素未被使用时,当前元素才会被考虑。所以只在使用前一个相同元素的情况下,才会使用当前元素,避免生成重复的排列。

                    意思就是,在已经确定了第二个元素时(也就是当前元素是true)而前一个元素是false时说明前一个元素肯定已经考虑过了,因为遍历是从左往右遍历,此时如果不进行continue,就会重复考虑相同元素,所以当used[i - 1] == false:时就cotinue

  1. 标记使用状态:

    • 在选择某个元素之后,将其标记为已使用:
       

      used[i] = true; path.push_back(nums[i]);

    • 进入递归调用,生成剩下的排列。
    • 递归完成后,回退状态:
       

      path.pop_back(); used[i] = false;

  2. 主函数 permuteUnique:

    • 初始化 result 和 path,并创建一个布尔数组 used 来跟踪元素使用状态,调用 backtracking 函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1952692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】透析类和对象(下)

有不懂的可以翻阅我之前文章&#xff01; 个人主页&#xff1a;CSDN_小八哥向前冲 所属专栏&#xff1a;CSDN_C入门 目录 拷贝构造函数 运算符重载 赋值运算符重载 取地址运算符重载 const成员函数 取地址重载 再探构造函数 初始化列表 类型转换 static成员 友元 内…

LLMs之Llama 3.1:Llama 3.1的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama 3.1&#xff1a;Llama 3.1的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年7月23日&#xff0c;Meta重磅推出Llama 3.1。本篇文章主要提到了Meta推出的Llama 3.1自然语言生成模型。 背景和痛点 >> 过去开源的大型语言模型在能力和性能上一…

vmware虚拟机安装linux没有IP地址

直接设置固定IP 1、在虚拟机菜单栏选择编辑&#xff0c;然后点击虚拟网络编辑器 2、选择Vmnet8 Net网络连接方式&#xff0c;随意设置子网IP 3、点击NAT设置页面&#xff0c;查看子网掩码和网关&#xff0c;修改静态IP会用到 4、打开电脑控制面板–网络和Internet–网络连…

Visual Studio 智能代码插件:Fitten Code

Fitten Code 是由非十大模型驱动的AI编程助手&#xff0c;它可以自动生成代码&#xff0c;提升开发效率&#xff0c;协助调试 Bug&#xff0c;节省时间。还可以对话聊天&#xff0c;解决编程碰到的问题。 Fitten Code 免费且多种编程语言&#xff0c;包括 Python、C、Javascri…

【CG】计算机图形学(Computer Graphics)基础(其贰)

0 学习视频 B站GAMES101-现代计算机图形学入门-闫令琪 ※ 接上文【CG】计算机图形学&#xff08;Computer Graphics&#xff09;基础&#xff08;其壹&#xff09; 7 光线追踪 7.1 为什么需要光线追踪&#xff1f; 光栅化无法妥善处理全局效果 &#xff08;软&#xff09;阴…

sizeof和strlen区别

如图&#xff0c;sizeof来计算的时候&#xff0c;得出的是计算机用多少个字节来表示一个地址 而strlen来计算的时候&#xff0c;只是计算出他的有效字符长度 打印出的不同地址就是其不同的区别

数据中心同步指南 : 数据中心架构师和其他网络专家需要了解有关 5G 同步的知识

随着 5G 的推出&#xff0c;电信基础设施的设计方式正在发生巨大变化。由于网络运营商希望创建更开放的网络基础设施生态系统&#xff0c;部分基础设施&#xff08;如基带处理&#xff09;被虚拟化并移至电信数据中心。影响数据中心架构的另一个与 5G 相关的趋势是移动边缘计算…

20240727 每日AI必读资讯

&#x1f310;OpenAI向Google宣战&#xff0c;重磅推出AI搜索引擎SearchGPT &#xff01; - 将 AI 与实时网络信息结合 提供生成式UI结果 - SearchGPT 结合网络最新信息可以直接回答问题&#xff0c;同时注明相关来源链接。 - 还可以像与人对话一样提出后续问题&#xff0c;…

YOLOv8 改进 | 注意力机制 | 处理原始SE通道信息丢失问题的ESE【含分割,检测,OBByaml文件】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

开放式耳机哪个品牌值得入手?五大年度黑马产品推荐

近几年开放式耳机获得了越来越多消费者的青睐&#xff0c;其中十分重要的原因就是&#xff0c;它能在不降低佩戴体验感的同时&#xff0c;让我们在不同的环境中尽情享受音乐。对于刚刚接触开放式耳机的朋友们来说&#xff0c;挑选一款在自己不踩雷的开放式耳机并非易事&#xf…

关于同一型号单片机使用不同版本的Keil5.pack包导致编译找不到对应.h问题

1.单片机型号:STM32G070CBTX 2.过程分析 拿到一个完整的工程&#xff0c;打开后编译报错&#xff0c;一些.h文件找不到&#xff0c;导致一些宏定义报错&#xff0c;如下图所示: 刚开始怀疑是安装的pack问题&#xff0c;又去ARM官网上下载最新的STM32G0xx_DFP.1.5.0版本的pack包…

吴恩达的TranslationAgent学习

TranslationAgent构成 整个[TranslationAgent (github.com)]在流程上分为短文本的一次性翻译和长文本的分chunk翻译&#xff08;按照Token进行划分&#xff09;。 但是不论长文本翻译还是短文本翻译&#xff0c;总体流程遵循执行、纠正再执行的逻辑循环实现。 这种按照自省思路…

Android ContentResolver.loadThumbnail转Kotlin

Android ContentResolver.loadThumbnail转Kotlin loadThumbnail原先是Java实现的&#xff0c;现在抠出来转Kotlin实现。 private fun loadThumbnail(uri: Uri, size: Size, signal: CancellationSignal): Bitmap {return myLoadThumbnail(mContext?.contentResolver!!, uri, s…

基于Qt的视频剪辑

在Qt中进行视频剪辑可以通过多种方式实现&#xff0c;但通常需要使用一些额外的库来处理视频数据。以下是一些常见的方法和步骤&#xff1a; 使用FFmpeg FFmpeg是一个非常强大的多媒体框架&#xff0c;可以用来处理视频和音频数据。你可以使用FFmpeg的命令行工具或者其库来实现…

Qemu和宿主机不使用外网进行文件传输

简介 目前Qemu虚拟机和宿主机交互&#xff0c;最方便的方式是进行网络传输&#xff0c;但也有不能使用外网的情况&#xff0c;这时候使用挂载是比较好的方式。 Linux使用 宿主机&#xff1a;Linux Qemu&#xff1a;Linux 传输方式&#xff1a;挂载 参考&#xff1a;在QEMU虚拟…

深圳市索迪迈科技有限公司:车载视频监控领域的精英

位于科技创新前沿的深圳市&#xff0c;索迪迈科技有限公司是一家专业从事车载视频监控设备研发、生产、销售的高新技术企业。公司自成立起&#xff0c;一直专注于车载设备领域的研发、生产、经营、服务一体化&#xff0c;为市场提供卓越的车载监控产品。 自主专业&#xff0c;专…

MySQL练习(4)

作业要求&#xff1a; 实现过程&#xff1a; 1.新建数据库 2.新建表 3.处理表 &#xff08;1&#xff09;修改student 表中年龄 (sage) 字段属性&#xff0c;数据类型由 int 改变为 smallint 。 &#xff08;2&#xff09;为 Course 表中 Cno 课程号字段设置索引,并查看索引。…

C语言边界互通传送迷宫

目录 注意事项开头程序程序的流程图程序输入与输出的效果结尾 注意事项 程序里有关字符’\033’的输出都关于Sunshine-Linux的其中一篇博客——《printf函数高级用法设置打印字体颜色和背景色等》 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们来看一下我用C语…

dpdk编译安装以及接收udp报文(基于ubuntu)

目录 1、编译 2、设置运行环境 3、使用dpdk接收udp报文 3.1、设置发送端arp信息 3.2、测试 3.3、代码 4、其他 1、编译 代码下载&#xff1a; DPDK 下载版本&#xff1a;DPDK 19.08.2 export RTE_SDK/root/dpdk-stable-19.08.2/ export RTE_TARGETx86_64-native-li…