网络异常,图片无法展示
|
「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
给你一个整数数组 nums
,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
示例 1:
输入: 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:
输入: nums = [4,4,3,2,1] 输出: [[4,4]] 复制代码
提示:
1 <= nums.length <= 15
-100 <= nums[i] <= 100
解题思路
首先我们观察示例1 的答案可以看到,本题的递增子序列,并不是严格递增,后面的元素是可以等于前面的元素的。
第二点,是关于本题的提示,如果含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。这句话的意思其实是说我们的答案中,不允许有重复的元素。比如前面的 4,6
可以和第一个 7
组成 4,6,7
,也可以和第二个 7
组成 4,6,7
,但是我们的结果数组中只有一个 4,6,7
,所以我们要对结果去重。
接下来我们再观察示例1 的答案可以看到,它其实就是以每一个元素为起点,向后查找递增子序列,然后将找到的递增子序列放入结果数组即可。这里我们不需要以最后一个元素为起点进行查找,是因为本题要求递增子序列中至少要有两个元素。
基于以上信息,我们就得到了本题的解题思路:
- 以除了最后一个元素的每一个元素为起点,向后查找符合条件的元素,组成递增子序列,并将组成的递增子序列插入结果数组。
- 在这个过程中,要注意有相同元素的情况,这里我们可以利用
Set
记录已经使用过的数字,如果后面找到的数字已经被使用过,则跳过。
代码实现
var findSubsequences = function(nums) { // 记录输入数组长度 const len = nums.length, // 初始化结果数组 res = []; // 根据给定子序列和开始下标,向后查找符合要求的元素,组成新的递增子序列 function getList(arr,l){ // 初始化 set 记录使用过的数字 const set = new Set(), // 获取当前子序列最后一个元素 end = arr[arr.length-1] // 遍历未处理区间 for(let i = l;i<len;i++){ const item = nums[i] // 如果当前数字使用过或者不符合要求,跳过 if(set.has(item) || item<end) continue; // 否则记录该数字 set.add(item) // 获取新的递增子序列 const _arr = [...arr,item] // 将子序列插入结果数组 res.push(_arr) // 继续查找可能的子序列 getList(_arr,i+1) } } // 创建 set 记录使用过的数字 const set = new Set(); // 遍历输入数组,以每一个元素为起点,查找递增子序列 for(let i = 0;i<len-1;i++){ const item = nums[i] if(set.has(item)) continue set.add(item) getList([item],i+1) } // 返回结果数组 return res; }; 复制代码
至此我们就完成了 leetcode-491-递增子序列
如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻