首页 > 编程语言 >C++算法练习-day61——90.子集2

C++算法练习-day61——90.子集2

时间:2024-12-05 20:01:14浏览次数:12  
标签:nums 元素 pos C++ day61 vector 子集 回溯 90

题目来源:. - 力扣(LeetCode)

题目思路分析

题目要求找出给定数组的所有子集(幂集),但数组可能包含重复元素,要求结果中的子集是唯一的(不包含重复的子集)。为了解决这个问题,我们可以先对数组进行排序,然后在回溯过程中跳过重复的元素,以确保生成的每个子集都是唯一的。

代码:

#include <vector>  
#include <algorithm> // 包含sort函数  
  
class Solution {  
public:  
    // 回溯函数,用于生成所有唯一的子集  
    void Backstracking(vector<vector<int>>& ans, vector<int>& pos, vector<int>& nums, int index) {  
        // 当遍历到数组的末尾或已经遍历完所有可能的元素时,将当前构建的子集加入结果集中  
        if (index == nums.size()) {  
            ans.push_back(pos); // 将当前子集pos加入结果集ans  
            return; // 返回上一层继续构建其他子集(但实际上这里不会返回,因为函数会在循环结束后自然结束)  
        }  
          
        // 遍历当前index之后的所有元素(由于数组已排序,可以利用这个性质跳过重复元素)  
        for (int i = index; i < nums.size(); ++i) {  
            // 如果当前元素与前一个元素相同(且不是第一个元素,因为第一个元素总是可以加入的),则跳过当前元素  
            // 这是为了确保生成的每个子集都是唯一的  
            if (i > index && nums[i] == nums[i - 1]) {  
                continue;  
            }  
              
            pos.push_back(nums[i]); // 将nums[i]加入当前子集pos  
            Backstracking(ans, pos, nums, i + 1); // 递归调用,尝试加入下一个元素  
            pos.pop_back(); // 回溯,撤销选择,尝试其他可能的子集  
        }  
    }  
  
    // 主函数,用于调用回溯函数并返回所有唯一的子集  
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {  
        vector<vector<int>> ans; // 存储所有子集的结果集  
        vector<int> pos; // 当前正在构建的子集  
        sort(nums.begin(), nums.end()); // 对数组进行排序,以便在回溯过程中跳过重复元素  
        Backstracking(ans, pos, nums, 0); // 从第一个元素开始构建子集  
        return ans; // 返回所有唯一的子集  
    }  
};

知识点摘要

  1. 回溯算法:通过递归尝试构建解的一部分,并在每一步决定是否继续构建或撤销当前选择,以探索所有可能的解。
  2. 递归:函数调用自身的方法,常用于解决可以分解为相似子问题的问题。
  3. 向量(Vector):C++ STL中的动态数组,可以动态增长和缩小。
  4. 排序:对数组进行排序,以便在回溯过程中利用排序后的性质(如跳过重复元素)。
  5. 条件判断:在回溯算法中,条件判断用于确定何时停止递归(即找到了一个解)和何时回溯(即撤销当前选择,尝试其他可能的解)。

通过回溯算法和排序的结合,我们可以有效地生成给定数组的所有唯一子集。在回溯过程中,我们利用排序后的数组性质,跳过重复的元素,以确保生成的每个子集都是唯一的。这种方法不仅适用于包含重复元素的子集问题,还可以扩展到其他需要生成唯一组合或排列的问题。通过理解回溯算法的基本原理和排序的应用,我们可以解决许多看似复杂的问题,并生成所需的所有唯一解。

标签:nums,元素,pos,C++,day61,vector,子集,回溯,90
From: https://blog.csdn.net/L613Z/article/details/143269606

相关文章

  • C++算法练习-day60——78.子集问题
    题目来源:.-力扣(LeetCode)题目思路分析题目要求找出给定数组的所有子集(幂集)。子集是指原数组中任意元素组合形成的数组,包括空集和原数组本身。这个问题可以通过回溯算法(Backtracking)来解决。回溯算法是一种通过探索所有可能的候选解来找出所有解的算法。对于子集问题,我们可以......
  • C++对象模型实践探索
    前言C++对象模型是个常见、且复杂的话题,本文基于ItaniumC++ABI通过程序实践介绍了几种简单C++继承场景下对象模型,尤其是存在虚函数的场景,并通过图的方式直观表达内存布局。本文展示的程序构建环境为Ubuntu,glibc2.24,gcc6.3.0。由于clang和gcc编译器都是基于ItaniumC++......
  • 【C++动态规划 BFS 博弈】3283. 吃掉所有兵需要的最多移动次数|2473
    本文涉及知识点C++动态规划C++BFS算法数学博弈LeetCode3283.吃掉所有兵需要的最多移动次数给你一个50x50的国际象棋棋盘,棋盘上有一个马和一些兵。给你两个整数kx和ky,其中(kx,ky)表示马所在的位置,同时还有一个二维数组positions,其中positions[i]=[x......
  • 超 90% 研发人员使用通义灵码,盖雅工场打造研发提效驾驶舱
    盖雅工场是一家提供人效数字化解决方案的中国企业,从员工激励的三个因子——精力、动力、能力出发,打造了基于时间-技能-动能的人效飞轮,人本主义提升员工体验,赋能发展助推效能提升,实现组织与员工的双向奔赴,企业、员工和社会三赢。作为人效数字化领域的领军企业,盖雅工场长期以来专......
  • 超 90% 研发人员使用通义灵码,盖雅工场打造研发提效驾驶舱
    盖雅工场是一家提供人效数字化解决方案的中国企业,从员工激励的三个因子——精力、动力、能力出发,打造了基于时间-技能-动能的人效飞轮,人本主义提升员工体验,赋能发展助推效能提升,实现组织与员工的双向奔赴,企业、员工和社会三赢。作为人效数字化领域的领军企业,盖雅工场长期以来专......
  • 超 90% 研发人员使用通义灵码,盖雅工场打造研发提效驾驶舱
    盖雅工场是一家提供人效数字化解决方案的中国企业,从员工激励的三个因子——精力、动力、能力出发,打造了基于时间-技能-动能的人效飞轮,人本主义提升员工体验,赋能发展助推效能提升,实现组织与员工的双向奔赴,企业、员工和社会三赢。作为人效数字化领域的领军企业,盖雅工场长期以来专......
  • C++(fprintf())
    目录1.函数定义2.常见格式说明符3.示例代码4.适用场景fprintf()是C和C++中用于格式化输出到文件的标准库函数。它的功能类似于printf(),但与printf()不同的是,fprintf()将格式化后的数据输出到指定的文件,而不是标准输出流(通常是屏幕)。1.函数定义intfprintf(FILE......
  • (2024最新毕设合集)基于SSM的河北省博物馆管理系统-02350|可做计算机毕业设计JAVA、PHP
    目 录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2 河北省博物馆管理系统系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3操作可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析......
  • 【C++】7000字剖析红黑树的概念规则和底层代码实现
    目录一、红黑树的概念二、怎么做到最长路径与最短路径相差小于等于两倍?(性质)     三、极端场景分析最长路径和最短路径:四、AVL树和红黑树的效率对比:五、树的路径包括叶子结点的空结点六、红黑树的插入结点时的相关规则:(一)、插入结点的颜色必须为红色(二)、处理规......
  • 冷门知识点:C++如何调试
    哈喽大家好,我是@学霸小羊,今天讲一个比较冷门的东西:C++如何调试。前几天我想要调试一个代码,搞半天,还没调出来。我在网上搜了半天,都是要下载一些诸如gdb之类的软件,我实在是不想下载这些五花八门的软件了,于是和我的损友研究了半天,总算研究出来了。注:以Dev-C++ 5.10版本进行讲......