「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
491. 递增子序列
给你一个整数数组 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
暴力求解+递归
思路 从题目中可以看出我们要求出所有的递增子序列,长度最少为2
那么我们就用递归+遍历的方式来做吧
首先我们可以从示例1中看出,我们可以先求出以4开头的所有结果,再从6开始开头的所有结果,继续遍历下去...直到数组的倒数第二个元素,因为最后一个元素是无法满足题意的
看到4,6,7 我们肯定可以想到会存在两个4,6,7 因为题目中存在两个7,最后必然需要去重,这里我们换了一个方式,用set保存序列化结果,这样就能自动去重了
具体实现:
- 声明一个res的set数据结构,用来保存所有的序列化结果
- 声明find函数来进行递归处理,这里接受两个参数,head(已经被选择的元素)和last(剩余未被选择的元素)
- 在find中我们遍历last,如果满足题意last中的元素item大于head中的最后一个元素,则将item,放入head中,组成一个新的结果newVal,并且序列化保存到res中
- 接下来我们只需要将刚才的newVal作为一个新的head,将last中还未被选择元素即i之后的元素,重新递归调用find即可
- 经过find的递归调用我们已经拿到所有以4开头的递增子序列结果,接下来只需要在开头 对nums进行循环,以nums中的每一个元素作为开头进行循环调用find即可
- 最后我们会得到一个res中保存着所有的序列化结果,遍历res将结果再转为数组放入result中返回即可
var findSubsequences = function (nums) {
var res = new Set()
for (var i = 0; i < nums.length - 1; i++) {
var head = nums[i];
find([head], nums.slice(i + 1))
}
function find(head, last) {
for (var i = 0; i < last.length; i++) {
var item = last[i];
var pre = head[head.length - 1]
if (item >= pre) {
var newVal = [...head, item]
res.add(JSON.stringify(newVal))
// 开启新篇章
find(newVal, last.slice(i + 1))
}
}
}
//
var result = []
for (let item of res) {
result.push(JSON.parse(item))
}
return result
};