
1 回溯法(first索引+跳过未排序重复元素)
刚开始分析题目时,考虑到输入有重复元素,我先
sort
了一下,发现不行,因为题目要求是找到所给数组当前顺序下的递增序列。但是不同顺序的两个解被视为同1个解,因此适合用组合惯用技巧
first
索引,但要想去除输入重复解的情况,又不能
sort
,那最通用的方法就是把当前层的选择通通扔到
1
个
哈希集合
中,只要有重复就选择性
continue
【问题考察本质】:通用型组合去重(可去非相邻重复而非sort后的相邻去重)
本题策略
- first索引避免乱序重复
- 跳过重复元素(
代替set.count(nums[i])
)nums[i-1] == nums[i]
class Solution {
private:
int size;
vector<vector<int>> solution;
vector<int> path;
public:
void backtrack(vector<int>& nums, int first) {
if (path.size() >= 2)
solution.emplace_back(path);
unordered_set<int> set;
// 1.first索引避免乱序重复
for (int i = first; i < size; i++) {
// 2.跳过重复元素(set.count(nums[i])代替nums[i-1] == nums[i])
if (set.count(nums[i])) continue;
if (!path.empty() && path.back() > nums[i]) continue;
set.insert(nums[i]);
path.emplace_back(nums[i]);
backtrack(nums, i + 1);
path.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
size = nums.size();
backtrack(nums, 0);
return solution;
}
};
复制
由于额外使用哈希集合来存储决策树每层的选择,因此时间和存储都高一点,可以使用哈希表进行优化,有兴趣的读者可以进一步思考
致谢
图片来源于「代码随想录」公众号,欢迎大家关注这位大佬的公号