1. 非递减子序列问题解析
今天我们来拆解LeetCode第491题——非递减子序列。这道题要求我们找出给定整数数组中所有可能的非递减子序列,且子序列长度至少为2。看似简单,但实际实现中有不少细节需要注意。
1.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]]
注意[4,7,6]不是有效子序列,因为7和6的顺序与原始数组不符。
1.2 核心挑战分析
这道题的主要难点在于:
- 如何高效生成所有可能的子序列
- 如何避免重复子序列的产生
- 如何确保子序列是非递减的
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. DFS回溯解法详解
2.1 算法思路
我们采用深度优先搜索(DFS)结合回溯的方法来解决这个问题。基本思路是:
- 从数组第一个元素开始,逐个尝试将元素加入当前路径
- 每次加入时检查是否满足非递减条件
- 当路径长度≥2时,将其加入结果集
- 使用哈希表记录当前层级已使用的元素,避免重复
2.2 代码实现解析
让我们仔细分析提供的Go代码实现:
go复制func findSubsequences(nums []int) [][]int {
var ans [][]int
var path []int
var dfs func(idx int)
dfs = func(idx int) {
if len(path) > 1 {
tmp := make([]int, len(path))
copy(tmp, path)
ans = append(ans, tmp)
}
usedMap := make(map[int]bool)
for i := idx; i < len(nums); i++ {
if usedMap[nums[i]] {
continue
