Java 求解递增子序列
Posted 南淮北安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 求解递增子序列相关的知识,希望对你有一定的参考价值。
一、题目
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是 2 。
二、题解
而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了
所以不能使用之前的去重逻辑:加一个标记数组去重
(1)递归函数参数
本题求子序列,很明显一个元素不能重复使用,所以需要 startIndex,调整下一层递归的起始位置。
(2)终止条件
本题其实类似求子集问题,也是要遍历树形结构找每一个节点,所以和回溯算法:求子集问题!一样,可以不加终止条件,startIndex每次都会加1,并不会无限递归。
但本题收集结果有所不同,题目要求递增子序列大小至少为2,所以代码如下:
if (deque.size() > 1)
// 不能直接 return,因为还没取完
lists.add(new ArrayList<>(deque));
(3)单层搜索逻辑
从图中可以看出,同层使用过的元素就不能再使用了
因为本题只要同层重复使用元素,递增子序列就会重复,所以需要一个去重逻辑,但是和以前的相邻元素去重不一样,这里可以设置一个 set 集合,每一层每个元素存入一次
// 每一层都会创建一个 set 集合
Set<Integer> set = new HashSet<>();
还有一种情况就是如果选取的元素小于子序列最后一个元素,那么就不能是递增的,所以也要pass掉。
for (int i = startIndex; i < nums.length; i++)
if ((!deque.isEmpty() && deque.getLast() > nums[i])
|| set.contains(nums[i]))
continue;
三、代码
class Solution
List<List<Integer>> lists = new ArrayList<>();
Deque<Integer> deque = new LinkedList<>();
public List<List<Integer>> findSubsequences(int[] nums)
backTrackeing(nums, 0);
return lists;
private void backTrackeing(int[] nums, int startIndex)
if (deque.size() > 1)
// 不能直接 return,因为还没取完
lists.add(new ArrayList<>(deque));
// 每一层都会创建一个 set 集合
Set<Integer> set = new HashSet<>();
for (int i = startIndex; i < nums.length; i++)
if ((!deque.isEmpty() && deque.getLast() > nums[i])
|| set.contains(nums[i]))
continue;
set.add(nums[i]);
deque.addLast(nums[i]);
backTrackeing(nums, i + 1);
deque.removeLast();
四、总结
本题要求找数组的递增 子序列,所以和以前的不一样,不能排序,每一层节点只能存入一次,可以借助 set 集合
能够排序的:排序+标志数组
不能够排序:set 集合
以上是关于Java 求解递增子序列的主要内容,如果未能解决你的问题,请参考以下文章