leetcode491(递增子序列:回溯法)

给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是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]]

题解(一):利用回溯法找到数组所有的子序列,然后判断该子序列是否是递增序列,同时也要维护一个哈希表用于去重

class Solution {
    
    
    /*
    * res用于存储最终结果
    * stack用于实现回溯算法
    * check用于去重
    */
    List<List<Integer>> res=new ArrayList<>();
    Stack<Integer>stack=new Stack<>();
    HashSet<ArrayList<Integer>>check=new HashSet<>();

    public List<List<Integer>> findSubsequences(int[] nums) {
    
    
        for(int i=0;i<nums.length;i++){
    
    
            stack.push(nums[i]);
            DFS(nums,i);
            stack.pop();
        }
          return res;
    }
    private void DFS(int[] nums,int index){
    
    
        for(int i=index+1;i<nums.length;i++){
    
    
            if(nums[i]>=stack.peek()){
    
    
                stack.push(nums[i]);
                ArrayList<Integer>subRes=new ArrayList<>();

                for(int x:stack)
                    subRes.add(x);

                if(!check.contains(subRes)) {
    
    
                    check.add(subRes);
                    res.add(subRes);
                }

                DFS(nums,i);

                stack.pop();
            }
        }
    }
}

题解(二):利用二进制枚举法同样可以找到数组所有的子序列

class Solution {
    
    
    public List<List<Integer>> findSubsequences(int[] nums) {
    
    
             List<List<Integer>>res=new LinkedList<>();
             Set<List<Integer>>check=new HashSet<>();
             int len= nums.length;
             /*
             * 子序列一共有(1<<len)种情况,区间[0,1<<len)中的每一个整数转换
             * 为二进制数后都代表一个子序列,若该二进制数的某一位为1,则取下标与其
             * 对应的数组数字,若为0,则不取
             */
             for(int i=1;i<=(1<<len);i++){
    
    
                 List<Integer>temp=getSubSequences(nums,i);
                 if(temp!=null&&temp.size()>=2&&!check.contains(temp)){
    
    
                     res.add(temp);
                     check.add(temp);
                 }
             }
             return res;
    }
    private List<Integer>getSubSequences(int []nums,int order){
    
    
        List<Integer>subSequence=new ArrayList<>();
        int index=0;
        while(order>0){
    
    
            /*
            * 找出数字order转换为二进制数字后1出现的位置,
            * 然后将该位置对应下标的数组数字加入序列
            */
            if((order&1)==1){
    
    
                int len=subSequence.size();
                if(subSequence.isEmpty()||nums[index]>=subSequence.get(len-1))
                    subSequence.add(nums[index]);
                else return null;

            }
            order>>=1;
            index++;
        }
        return subSequence;
    }
}

猜你喜欢

转载自blog.csdn.net/CY2333333/article/details/108217833