LeetCode_88_IncreasingSubsequences


1. question: 递增子序列(中等)

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/increasing-subsequences

示例 1:

1
2
输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

示例 2:

1
2
输入:nums = [4,4,3,2,1]
输出:[[4,4]]

提示:

1
2
1 <= nums.length <= 15
-100 <= nums[i] <= 100

2. answers

注意,本道题是找子序列,意味着结果中的序列中的元素,对于给定数组的元素的相对位置是不能改变的,即我们不能对数组进行排序。

那么这样的话,就不能对数组排序进行去重了。所以必须针对统一位置的元素的不同选择进行去重。可设置一个辅助结构,存储已经选择的元素。当再次选择时,判断是否已经选择过即可。这就可以去重了。

另外,要保证是递增的,所以在选择元素的时候,除了判断重复,还要判断是否大于等于序列的最后一个元素。

注意,子序列的长度要大于等于2。递归条件和子集类似,不需要设置递归条件,只需要循环结束即可。

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class Solution_0087 {

List<List<Integer>> result = new ArrayList<>();

LinkedList<Integer> group = new LinkedList<>();


public void findPar(int[] nums, int startIndex) {

// 定义哈希表,存储已经选过的选择
HashSet<Integer> hs = new HashSet<>();

for (int i = startIndex; i < nums.length; i++) {

// 保证大于上一个元素,并且保证当前位置的元素和已经的选择不重复
if(hs.contains(nums[i]) || (group.size() > 0 && nums[i] < group.getLast())) continue;
hs.add(nums[i]);
group.add(nums[i]);

if(group.size() > 1) result.add(new ArrayList<>(group));

// 递归下一位
findPar(nums, i + 1);

// 回溯
group.removeLast();
}

}


public List<List<Integer>> findSubsequences(int[] nums) {

findPar(nums, 0);

return result;
}

public static void main(String[] args) {
System.out.println();

int[] nums = {4, 6, 7, 7};
// int[] nums = {4, 4, 3, 2, 1};

Solution_0087 s = new Solution_0087();

List<List<Integer>> result = s.findSubsequences(nums);

for(List<Integer> list: result){

for(Integer i: list)
System.out.print(i + "\t");

System.out.println();
}

}
}

3. 备注

参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com)代码随想录 (programmercarl.com)


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录