s0491
All checks were successful
ci/woodpecker/push/test Pipeline was successful

This commit is contained in:
Sainnhe Park 2023-02-03 13:11:13 +08:00
parent e347731fef
commit 3171c30f82
3 changed files with 84 additions and 0 deletions

View File

@ -0,0 +1,14 @@
#ifndef S0491_NON_DECREASING_SUBSEQUENCES_HPP
#define S0491_NON_DECREASING_SUBSEQUENCES_HPP
#include <unordered_map>
#include <vector>
using namespace std;
class S0491 {
public:
vector<vector<int>> findSubsequences(vector<int>& nums);
};
#endif

View File

@ -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<int> &subsequences, vector<vector<int>> &result,
vector<int> &nums, int startIndex) {
int size = nums.size();
// 结束条件
if (startIndex == size) return;
// 初始化一个哈希表用来存储元素是否在数层中使用过
unordered_map<int, bool> 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();
}
}
}
```
这种去重逻辑相比于之前的去重逻辑起始开销更大,因为每一层遍历都要创建一个新的哈希表,而之前的去重逻辑每一层遍历都用的是之前创建的向量。

View File

@ -0,0 +1,31 @@
#include "s0491_non_decreasing_subsequences.hpp"
void findSubsequencesDFS(vector<int> &subsequences, vector<vector<int>> &result,
vector<int> &nums, int startIndex) {
int size = nums.size();
// 结束条件
if (startIndex == size) return;
// 初始化一个哈希表用来存储元素是否在数层中使用过
unordered_map<int, bool> 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<vector<int>> S0491::findSubsequences(vector<int> &nums) {
vector<int> subsequences{};
vector<vector<int>> result{};
findSubsequencesDFS(subsequences, result, nums, 0);
return result;
}