0
点赞
收藏
分享

微信扫一扫

leetcode 491. 递增子序列

禾木瞎写 2023-07-26 阅读 59

2023.7.23

         本题本质上也是要选取递归树中的满足条件的所有节点,而不是选取叶子节点。 故在将符合条件的path数组放入ans数组后,不要执行return。 还一点就是这个数组不是有序的,并且也不能将它有序化,所以这里的去重操作不能和之前一样了,需要定义一个set容器存储每层元素的使用情况,即同一父节点下的同一层不能使用同一个元素。

        我定义了个判别path是否递增的函数,绕了弯子,下面看代码:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    bool is_sort(vector<int> nums)
    {
        for(int i=0; i<nums.size(); i++)
        {
            if(i>0 && nums[i]<nums[i-1])
            {
                return false;
            }
        }
        return true;
    }
    void backtrating(vector<int> nums,int start)
    {
        if(path.size()>=2 && is_sort(path)) //此处不需要return,因为我们要加入的是树的所有节点而不是叶子节点。
        {
            ans.push_back(path);
        }
        //if(start >= nums.size()) return;
        unordered_set<int> used;
        for(int i=start; i<nums.size(); i++)
        {
            if(used.find(nums[i]) != used.end()) continue;//找到重复使用的元素 跳过本次循环
            used.insert(nums[i]);
            path.push_back(nums[i]);
            backtrating(nums,i+1);
            path.pop_back();
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        backtrating(nums,0);
        return ans;
    }
};

        下面看一下优化过后的,不需要定义判别递增的函数,在元素加入path前进行一次if判断:看加入之后是否符合递增:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    // bool is_sort(vector<int> nums)
    // {
    //     for(int i=0; i<nums.size(); i++)
    //     {
    //         if(i>0 && nums[i]<nums[i-1])
    //         {
    //             return false;
    //         }
    //     }
    //     return true;
    // }
    void backtrating(vector<int> nums,int start)
    {
        if(path.size()>=2) //此处不需要return,因为我们要加入的是树的所有节点而不是叶子节点。
        {
            ans.push_back(path);
        }
        //if(start >= nums.size()) return;
        unordered_set<int> used;
        for(int i=start; i<nums.size(); i++)
        {
            if(used.find(nums[i]) != used.end()) continue;//找到重复使用的元素 跳过本次循环
            if(!path.empty() && nums[i]<path.back()) continue; //若为非递增 跳过本次循环
            used.insert(nums[i]);
            path.push_back(nums[i]);
            backtrating(nums,i+1);
            path.pop_back();
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        backtrating(nums,0);
        return ans;
    }
};

        上述代码可以进行优化,上面代码使用set来记录重复元素,由于题目中给出了nums中元素的大小范围:-100~100. 所以可以用一个大小为201的数组记录nums中所有元素的使用情况:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    // bool is_sort(vector<int> nums)
    // {
    //     for(int i=0; i<nums.size(); i++)
    //     {
    //         if(i>0 && nums[i]<nums[i-1])
    //         {
    //             return false;
    //         }
    //     }
    //     return true;
    // }
    void backtrating(vector<int> nums,int start)
    {
        if(path.size()>=2) //此处不需要return,因为我们要加入的是树的所有节点而不是叶子节点。
        {
            ans.push_back(path);
        }
        //if(start >= nums.size()) return;
        //unordered_set<int> used;
        int used[201] ={0};
        for(int i=start; i<nums.size(); i++)
        {
            //if(used.find(nums[i]) != used.end()) continue;//找到重复使用的元素 跳过本次循环
            if(used[nums[i]+100] == 1) continue;
            if(!path.empty() && nums[i]<path.back()) continue; //若为非递增 跳过本次循环
            used[nums[i]+100] = 1;
            path.push_back(nums[i]);
            backtrating(nums,i+1);
            path.pop_back();
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        backtrating(nums,0);
        return ans;
    }
};
举报

相关推荐

0 条评论