diff --git a/include/s0491_non_decreasing_subsequences.hpp b/include/s0491_non_decreasing_subsequences.hpp new file mode 100644 index 0000000..19e0821 --- /dev/null +++ b/include/s0491_non_decreasing_subsequences.hpp @@ -0,0 +1,14 @@ +#ifndef S0491_NON_DECREASING_SUBSEQUENCES_HPP +#define S0491_NON_DECREASING_SUBSEQUENCES_HPP + +#include +#include + +using namespace std; + +class S0491 { + public: + vector> findSubsequences(vector& nums); +}; + +#endif diff --git a/notes/src/subsets.md b/notes/src/subsets.md index 4eaa8ac..19db122 100644 --- a/notes/src/subsets.md +++ b/notes/src/subsets.md @@ -3,3 +3,42 @@ ## [78. 子集](https://leetcode.cn/problems/subsets/) 其实和切割问题非常像。 + +## [90. 子集 II](https://leetcode.cn/problems/subsets-ii/) + +就是在 s0078 的基础上加了去重逻辑,和组合问题中的去重逻辑一样。 + +## [491. 递增子序列](https://leetcode.cn/problems/non-decreasing-subsequences/) + +也是要去重,但是不能通过排序去重,因为排序之后顺序就全部打乱了。 + +这个去重同样要保留树枝重复,但去除树层重复。 + +思路很简单,每一层遍历的时候创建一个哈希表,用来记录当前元素是否遍历过,如果遍历过则跳过。 + +```cpp +void findSubsequencesDFS(vector &subsequences, vector> &result, + vector &nums, int startIndex) { + int size = nums.size(); + // 结束条件 + if (startIndex == size) return; + + // 初始化一个哈希表用来存储元素是否在数层中使用过 + unordered_map used; + + for (int i = startIndex; i < size; ++i) { + // 剪枝,如果元素在数层中使用过则跳过 + if (used.count(nums[i]) == 1) continue; + // 当当前元素大于等于起始元素之前的元素时,将它添加进去 + if (startIndex == 0 || nums[i] >= nums[startIndex - 1]) { + subsequences.push_back(nums[i]); + if (subsequences.size() > 1) result.push_back(subsequences); + used[nums[i]] = true; + findSubsequencesDFS(subsequences, result, nums, i + 1); + subsequences.pop_back(); + } + } +} +``` + +这种去重逻辑相比于之前的去重逻辑起始开销更大,因为每一层遍历都要创建一个新的哈希表,而之前的去重逻辑每一层遍历都用的是之前创建的向量。 diff --git a/src/s0491_non_decreasing_subsequences.cpp b/src/s0491_non_decreasing_subsequences.cpp new file mode 100644 index 0000000..f83711e --- /dev/null +++ b/src/s0491_non_decreasing_subsequences.cpp @@ -0,0 +1,31 @@ +#include "s0491_non_decreasing_subsequences.hpp" + +void findSubsequencesDFS(vector &subsequences, vector> &result, + vector &nums, int startIndex) { + int size = nums.size(); + // 结束条件 + if (startIndex == size) return; + + // 初始化一个哈希表用来存储元素是否在数层中使用过 + unordered_map used; + + for (int i = startIndex; i < size; ++i) { + // 剪枝,如果元素在数层中使用过则跳过 + if (used.count(nums[i]) == 1) continue; + // 当当前元素大于等于起始元素之前的元素时,将它添加进去 + if (startIndex == 0 || nums[i] >= nums[startIndex - 1]) { + subsequences.push_back(nums[i]); + if (subsequences.size() > 1) result.push_back(subsequences); + used[nums[i]] = true; + findSubsequencesDFS(subsequences, result, nums, i + 1); + subsequences.pop_back(); + } + } +} + +vector> S0491::findSubsequences(vector &nums) { + vector subsequences{}; + vector> result{}; + findSubsequencesDFS(subsequences, result, nums, 0); + return result; +}