代码随想录算法训练营之JAVA|第二十五天| 491. 递增子序列

今天是第25天刷leetcode,立个flag,打卡60天。

算法挑战链接

491. 递增子序列https://leetcode.cn/problems/non-decreasing-subsequences/

第一想法

题目理解:在给定的一个数组中,找出全部的递增列表。要求不能有重复。

这是一个错误的思路

一开始的时候想着找一个递增列表,那不是简简单单?但是不能重复就有点复杂了。

首先解决相同的两个在一起的情况,比如 4,6,7,7 会出现两个4,7的列表,这个时候我就判断当前元素不能和上一元素一样。

如果列表中有重复的,1,2,3,1,1,就会出现1,1 这种重复的列表。然后又解决这个问题。

后面发现问题越来越多,解决不完。我就知道我陷入了一个不好循环中。目前我应该是完不成这道题目的。

看完代码随想录之后的想法 

解决问题应该从跳出细节来观察。

回溯的原理是将每一次的选择当成一个分支来看,于是我们就可以画图。如4,7,6,7代码随想录算法训练营之JAVA|第二十五天| 491. 递增子序列_第1张图片

 在途中我们可以看到 红色叉叉的路径上的点的特点,总结下来有如下特性:

1. 当前的元素节点不能小于上一个选择的元素节点

2. 同一层中,相同元素的不能往下递归

于是想要解决这个问题就简单很多了,我们只需要把满足这两个特性的节点去除掉即可。

看代码:

class Solution {
     List> results3 = new ArrayList<>();
    public  List> findSubsequences(int[] nums) {
        LinkedList result = new LinkedList<>();
        backtracking4(0, nums, result);
        return results3;
    }


     void backtracking4(int index, int[] nums, LinkedList result) {
        if (result.size() > 1) {
            results3.add(new ArrayList<>(result));
        }
        Set set = new HashSet<>();
        for (int i = index; i < nums.length; i++) {
            //第一个特性
            if (!result.isEmpty() && result.get(result.size() -1 ) > nums[i]) {
                continue;
            }
            //第二个特性
            if (set.contains(nums[i])) {
                continue;
            }
            set.add(nums[i]);
            result.add(nums[i]);
            backtracking4(i+1, nums, result);
            result.removeLast();
        }
    }
}

今日收获

1. 当陷入局部难题,并且难题越结越多的时候,应该跳出来观察问题,而不是继续纠结。

2. 学会去总结

你可能感兴趣的:(算法)