0
点赞
收藏
分享

微信扫一扫

LeetCode 491 递增子序列

琛彤麻麻 2022-04-17 阅读 72

重点是去重:

考虑一下去重问题,我使用了 O(n)O(n) 的判重方法:

设 stack 中最后一个值的位置为 last。如果 stack 为空,则 last = -1。
设当前正在处理的位置为 pos。
如果在 nums 的子区间 [last+1, pos) 中,存在和 nums[pos] 相同的值,则当前 nums[pos] 必须丢弃,不然会产生重复的子序列。

设现在 stack = [4, 6], pos = 4。
如果只检查是否递增的话,nums[4] = 7 是可以放入的,放入后 stack = [4, 6, 7]。
但是,当 stack = [4, 6] 时,last = 1,在 nums[last+1, 4) 中,还存在一个 nums[2] = 7。
这说明,在之前的递归中,已经构造出了 stack = [4, 6, 7] 这种情况。
所以,在 stack = [4, 6] 时,nums[4] = 7 应该丢弃。

当 stack = [4, 6, 7], pos = 4 时。

此时,last = 2pos = 4,此时 nums[last+1, pos) 中,并没有其他的 7 了。
且放入后,stack 还是递增子序列,所以构造出了 stack = [4,6,7,7]

class Solution {

    int[] pre = new int[15];
    public List<List<Integer>> findSubsequences(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            pre[i] = -1;
            for (int j = i - 1; j >= 0; j--) {
                if (nums[j] == nums[i]) {
                    pre[i] = j;
                    break;
                }
            }
        }
        List<List<Integer>> anw = new ArrayList<>();
        LinkedList<Integer> stack = new LinkedList<>();
        dfs(nums, -1, 0, stack, anw);
        return anw;
    }

        // 判重代码;
    public boolean is_first(int last, int pos) {
        return !(last < pre[pos] && pre[pos] < pos);
    }

    public void dfs(int[] nums, int last, int pos, LinkedList<Integer> stack, List<List<Integer>> anw) {
        if(nums.length == pos) { return; } //到达末尾,直接范围吧
        // 检查 nums[pos] 是否符合要求
        if((stack.isEmpty() || nums[pos] >= stack.peekLast()) && is_first(last, pos)) {
            stack.add(nums[pos]);
            if(stack.size() >= 2) { //大于 2 了,那就放进去吧
                anw.add(new ArrayList<>(stack));
            }
            dfs(nums, pos, pos+1, stack, anw); // 继续处理下一个。
            stack.pollLast(); // 将当前放入这个吐出来。
        }
        dfs(nums, last, pos+1, stack, anw);
    }
}

 

举报

相关推荐

0 条评论