LeetCode-491.递增子序列、深度优先搜索算法DFS

给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。
示例:
输入: [4, 6, 7, 7]
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
说明:
给定数组的长度不会超过15。
数组中的整数范围是 [-100,100]。
给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。
来源:力扣(LeetCode)第491题

解题思路

  1. 生成子序列
    数组的子序列,需要保证元素的相对位置关系和原数组中保存一致​。因此需要遍历数组从头到尾挑选元素,挑选的每一步可以有要、或者不要当前元素两种选择​;所有挑选情况的排列组合即为所有的子序列,判断满足条件的子序列​放入结果即可。
    对所有当前可能的选择遍历,即:深度优先搜索算法。
  2. 判断重复
    新加入的元素只能在当前子序列的最后一个元素对应的下标之后的位置进行挑选,若将要添加的元素值在该位置之后是​第一次出现的,则不重复。​

代码示例

class Solution {
public:
    vector<vector<int>> findSubsequences(vector<int>& nums) {
       
        vector<vector<int>> res;  
        vector<int> cur;//当前子序列
        dfs(res,cur,nums,0,-1);  
        return res;
        
    }
    //判断重复:要添加的元素值不是第一次出现即可
    //                                当前子序列末尾元素  要添加的元素
    bool checkCanAdd(vector<int>& nums,int  lastIndex,int curIndex)
    {
        for(int i = lastIndex+1;i < curIndex;++i)
        {
            if( nums[i] == nums[curIndex])
                return false;
        }
        return true;
    }
    void dfs( vector<vector<int>> &res, vector<int> &cur,vector<int>& nums,int curIndex ,int lastIndex)
    {
        if( curIndex >= nums.size() ) //超边界,没元素可选
        {
            //判断当前子序列
            if( cur.size() > 1)
                res.push_back(cur);
            return;
        }
        
        //遍历当前所有可能的选择:选择curIndex 、不选curIndex
        //选择curIndex
        if( cur.size() == 0 || nums[curIndex] >= cur.back())
        {
            if( checkCanAdd(nums,lastIndex,curIndex))//非重复
            {
                cur.push_back(nums[curIndex]);//可以加入序列
                dfs( res,cur,nums,curIndex+1,curIndex);
                cur.pop_back();//撤销选择
            }
        }
        //不选curIndex
        dfs( res,cur,nums,curIndex+1,lastIndex);
    }
       
};

在这里插入图片描述


版权声明:本文为lizhichao410原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。