• 491. 递增子序列


    • dp 解法(类似 bfs, 有些像杨辉三角)
        /**
         * 1. 加入当前数字会产生哪些新序列,只要遍历当前存在的序列并比较最后一个数字和当前数字,如果当前数字更大则加入产生新的序列
         * 2. 由 1 产生的新序列加上已经存在的序列以及当前数字作为一个新序列起点的情况作为新的结果
         * 3. 利用HashSet对list去重
         * 4. 最后过滤掉长度不足 2 的序列得到最终结果
         *
         *  nums = [4, 6, 7, 7]
         *
         *         [4]         [4]
         *         [4,6]       [4,6],[4],[6]
         *         [4,6,7]     [4,6,7],[4,7],[6,7],[4,6],[4],[6],[7]
         *         [4,6,7,7]   [4,6,7,7],[6,7,7],[4,7,7],[7,7],[4,6,7],[6,7],[4,7],[7],[4,6,7],[6,7],[4,7],[7],[4,6],[6],[4]
         *
         *
         *         result  =>  [4,6,7,7],[6,7,7],[4,7,7],[7,7],[4,6,7],[6,7],[4,7],[4,6]
         */
        public List<List<Integer>> findSubsequences(int[] nums) {
            Set<List<Integer>> dp = new HashSet<>();
            Set<List<Integer>> beforeDp;
            for (int i = 0; i < nums.length; i++) {
                beforeDp = new HashSet<>(dp);
                for (List<Integer> before : beforeDp) {
                    if(nums[i] >= before.get(before.size()-1)) { //加上新追加的列表
                        List<Integer> temp = new ArrayList<>(before);
                        temp.add(nums[i]);
                        dp.add(temp);
                    }
                    dp.add(before); //加上之前的列表
                }
                dp.add(Arrays.asList(nums[i])); //加上当前元素的
            }
            return dp.stream().filter(list -> list.size() >= 2).collect(Collectors.toList());
        }
    
    • dfs 解法(递归回溯+剪枝)
        /**
         * 考虑 nums={1,2,3}
         *
         * holder 的输出(不考虑剪枝和递增):
         * [1]
         * [1, 2]
         * [1, 2, 3]
         * [1, 2, 3, 3]
         * [1, 2, 3, 3, 2]
         * [1, 2, 3, 3, 2, 3]
         * [1, 2, 3, 3, 2, 3, 3]
         *
         * holder 的输出(考虑剪枝和递增):
         * [1]
         * [1, 2]
         * [1, 2, 3]
         * [1, 3]
         * [2]
         * [2, 3]
         * [3]
         *
         * result的结果
         * [[1, 2, 3], [1, 2], [2, 3], [1, 3]]
         */
        public List<List<Integer>> findSubsequences(int[] nums) { // 递归回溯(dfs) + 剪枝。只处理递增子序列,限制只取List大小>=2,并利用HashSet对List去重。
            List<Integer> holder = new ArrayList<>();
            Set<List<Integer>> result = new HashSet<>();
            dfs(0, nums, holder, result);
            return new ArrayList<>(result);
        }
        private void dfs(int index, int[] nums, List<Integer> holder, Set<List<Integer>> result) {
            if(holder.size() >= 2) {
                result.add(new ArrayList<>(holder));
            }
            for (int k = index; k < nums.length; k++) {
                if (holder.isEmpty() || nums[k] >= holder.get(holder.size() - 1)) { // 限制只处理 递增子序列
                    holder.add(nums[k]);
                    dfs(k + 1, nums, holder, result);
                    holder.remove(holder.size() - 1);
                }
            }
        }
    
  • 相关阅读:
    Java动态规划实现将数组拆分成相等的两部分
    动态规划解决hdu龟兔赛跑
    Eclipse上将maven项目部署到tomcat,本地tomcat下,webapps下,web-inf下lib下没有jar包决绝方案
    【转】spring IOC和AOP的理解
    Eclipse创建一个普通的java web项目
    linux服务器自动备份与删除postgres数据库数据
    开启Linux服务器vnc远程桌面详细步骤
    设计模式---JDK动态代理和CGLIB代理
    菜谱
    网络协议-dubbo协议
  • 原文地址:https://www.cnblogs.com/lasclocker/p/11443973.html
Copyright © 2020-2023  润新知