• 009. 递增子序列


    1.题目链接:

    491. 递增子序列

    2.解题思路:

    2.1.题目要求:

    给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 (数组可能有重复的元素,相等的元素排列也可以算递增)

    示例 :

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

    注意:不可以排序,比如 上面如果排序就全是递增子序列了,像 [1,2,3,4,4 ] 就全是递增子序列,但上面返回的只有 [ 4,4 ] ,说明题目要求要原生态的递增子序列,不能排序 。

    2.2.思路:

    for + 递归 构建 N叉树,用一个path 去记录每次递归的结果,然后每次元素个数大于 2 个就把path输入结果集。

    同时在单层搜索的逻辑中,需要判断 遍历位置的 num [ i ] 是否 大于等于 path的末尾值,同时在树层递归中需要判断选择的 num[ i ] 有没有被重复使用,重复使用的话跳过,这样来满足题目条件

    N叉树流程如下:

    2.3.回溯三部曲:

    2.3.1.确定回溯函数参数

    元素不能重复使用,所以需要startIndex,调整下一层递归的起始位置。

    代码如下:

    1. vectorint>> result;
    2. vector<int> path;
    3. void backtracking(vector<int>& nums, int startIndex)

    2.3.2.确定终止条件

     不加 >= 的逻辑也行,for 循环完成,函数会自然的结束,不过加上可能会方便理解点

    同时在这里 path.size() > 2 需要输入 path 到 result 里。

    代码如下:

    1. if (startIndex >= nums.size()) {
    2. return;
    3. }
    4. if (path.size() > 1) {
    5. result.push_back(path);
    6. // 注意这里不要加return,因为要取树上的所有节点
    7. }

    2.3.3.确定单层遍历逻辑

    这一部分,在搜集结果的同时,还需要排除 树层中重复的数不能变成递增子序列的情况,

    注意:uset每次都是新定义的,所以不需要回溯。

    代码如下:

    1. unordered_set<int> uset; // 使用set来对本层元素进行去重
    2. for (int i = startIndex; i < nums.size(); i++) {
    3. if ((!path.empty() && nums[i] < path.back())//path为空不进行判断
    4. || uset.find(nums[i]) != uset.end()) {
    5. continue;
    6. }
    7. uset.insert(nums[i]); // 记录这个元素在本层用过了,本层后面不能再用了
    8. path.push_back(nums[i]);
    9. backtracking(nums, i + 1);
    10. path.pop_back();
    11. }

    2.4.总代码:

    1. class Solution {
    2. private:
    3. vectorint>> result;
    4. vector<int> path;
    5. void backtracking(vector<int>& nums, int startIndex) {
    6. if (startIndex >= nums.size()) {
    7. return;
    8. }
    9. if (path.size() > 1) {
    10. result.push_back(path);
    11. // 注意这里不要加return,因为要取树上的所有节点
    12. }
    13. unordered_set<int> uset; // 使用set对本层元素进行去重
    14. for (int i = startIndex; i < nums.size(); i++) {
    15. if ((!path.empty() && nums[i] < path.back())
    16. || uset.find(nums[i]) != uset.end()) {
    17. continue;
    18. }
    19. uset.insert(nums[i]); // 记录这个元素在本层用过了,本层后面不能再用了
    20. path.push_back(nums[i]);
    21. backtracking(nums, i + 1);
    22. path.pop_back();
    23. }
    24. }
    25. public:
    26. vectorint>> findSubsequences(vector<int>& nums) {
    27. result.clear();
    28. path.clear();
    29. backtracking(nums, 0);
    30. return result;
    31. }
    32. };

    3.遇见的问题:

    Set 中查找一个元素(不明白干嘛要!= c.end( )...)

    1. Set<int> c;
    2. int target = 163;
    3. if (c.find(target) != c.end())
    4. {
    5. // find the target
    6. }

    unordered_set,无序set?

    不知道

    突然树层为什么不能重复选没想清楚

    答:像 [1,1,3,2,1]  可能会出现 [1,3] [1,3] 的情况,分别是第一个 1 和 第二个 1 。

    4.记录:

  • 相关阅读:
    使用C语言EasyX 创建动态爱心背景
    新星微前端MicroApp的基础教程
    如何弄懂复杂项目
    FPGA的256点FFT调用Quartus IP核实现VHDL傅里叶变换
    Linux服务器管理入门
    Yalmip使用教程(6)-将约束条件写成矩阵形式
    企业级高负载WEB服务器—Tomcat
    华为机试题输入输出总结
    python写入文件后读取空白,写入文件无法读取解决方案
    第二章 软件测试开发工程师
  • 原文地址:https://blog.csdn.net/qq_70280303/article/details/128169180