• 代码随想录算法训练营第23期day28|491.递增子序列 46.全排列 47.全排列 II


    目录

    一、(leetcode 491)递增子序列

    二、(leetcode 46)全排列

    三、(leetcode 47)全排列 II


    一、(leetcode 491)递增子序列

    力扣题目链接

    状态:去重方法错误。

    这道题和之前全排列的区别就在于不是对同一层的重复元素进行去重,而是去除同一父节点下的重复使用元素,为了达到这个目的,需要使用哈希来判断是否重复,注意到数组中值的大小是-100到100之间,因此可以直接利用哈希数组进行判断

    1. class Solution {
    2. public:
    3.     vectorint>> res;
    4.     vector<int> path;
    5.     void backtracking(vector<int>& nums, int startIndex){
    6.         if(path.size() >= 2){
    7.             res.emplace_back(path);
    8.         }
    9.         int len = nums.size();
    10.         int used[201] = {0};
    11.         for(int i = startIndex; i < len; ++i){
    12.             if((!path.empty() && path.back() > nums[i]) 
    13.             || used[nums[i] + 100] == 1){
    14.                 continue;
    15.             }
    16.             used[nums[i] + 100] = 1;
    17.             path.emplace_back(nums[i]);
    18.             backtracking(nums, i+1);
    19.             path.pop_back();
    20.         }
    21.     }
    22.     vectorint>> findSubsequences(vector<int>& nums) {
    23.         res.clear();
    24.         path.clear();
    25.         backtracking(nums, 0);
    26.         return res;
    27.     }
    28. };

    二、(leetcode 46)全排列

    力扣题目链接

    状态:查看思路后AC。

    注意全排列和组合(子集)的最大区别在于,全排列的回溯展开每次都是从0开始而不是startIndex,因此需要一个used数组来对已经使用过的节点进行记录,值得注意的是在pop之后,used数组也要进行更新

    1. class Solution {
    2. public:
    3.     vectorint>> res;
    4.     vector<int> path;
    5.     void backtracking(vector<int>& nums, vector<bool>& used){
    6.         if(path.size() == nums.size()){
    7.             res.emplace_back(path);
    8.             return;
    9.         }
    10.         for(int i = 0; i < nums.size(); ++i){
    11.             if(used[i]) continue;
    12.             used[i] = true;
    13.             path.emplace_back(nums[i]);
    14.             backtracking(nums, used);
    15.             path.pop_back();
    16.             used[i] = false;
    17.         }
    18.     }
    19.     vectorint>> permute(vector<int>& nums) {
    20.         res.clear();
    21.         path.clear();
    22.         vector<bool> used(nums.size(), false);
    23.         backtracking(nums, used);
    24.         return res;
    25.     }
    26. };

    三、(leetcode 47)全排列 II

    力扣题目链接

    状态:查看思路后也没AC。

    这里的去重逻辑和组合中的树层去重逻辑类似,注意细节。

    1. class Solution {
    2. public:
    3.     vectorint>> res;
    4.     vector<int> path;
    5.     void backtracking(vector<int>& nums, vector<bool>& used){
    6.         if(path.size() == nums.size()){
    7.             res.emplace_back(path);
    8.             return;
    9.         }
    10.         for(int i = 0; i < nums.size(); ++i){
    11.             if(i > 0 && nums[i-1] == nums[i] && used[i-1] == true) continue;
    12.             if(used[i] == false){
    13.                 used[i] = true;
    14.                 path.emplace_back(nums[i]);
    15.                 backtracking(nums, used);

  • 相关阅读:
    Linux与shell命令行学习
    C语言之文件操作(万字详解)
    vuex 中使用了modules,如何在页面中调用actions里面的方法
    得物App订单配置类文案测试右移实践
    化繁为简,聊一聊复制状态机系统架构抽象
    适用于Windows电脑的最佳数据恢复软件是哪些?10佳数据恢复软件
    充分条件、必要条件、充要条件
    C#进阶-ASP.NET常用控件总结
    【网络教程】IPtables官方教程--学习笔记1
    Tomcat运维以及优化
  • 原文地址:https://blog.csdn.net/weixin_42179093/article/details/133953519