Day 29 回溯算法
491. 递增子序列
如果直接像下面这样写的话,会出错,出错的案例类似:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9nrEEc2S-1688623883770)(LC491-递增子序列+LC.assets/image-20230703201315163.png)]
class Solution {
vector<vector<int>> rst;
vector<int> path;
void backtracking(const vector<int> &nums, int idx)
{
if (path.size() > 1)
{
rst.push_back(path);
}
for (int i = idx; i < nums.size(); i++)
{
if (i > idx && nums[i] == nums[i - 1]) // 不能使用这一去重逻辑
{
continue;
}
if (path.empty() || path.back() <= nums[i])
{
path.push_back(nums[i]);
backtracking(nums, i + 1);
path.pop_back();
}
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
rst.clear();
path.clear();
backtracking(nums, 0);
return rst;
}
};
本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。
所以不能使用之前的去重逻辑!
同一父节点下的同层上使用过的元素就不能再使用了
正确的写法如下:
class Solution {
vector<vector<int>> rst;
vector<int> path;
void backtracking(const vector<int> &nums, int idx)
{
if (path.size() > 1)
{
rst.push_back(path);
}
int used[201] = {0};
for (int i = idx; i < nums.size(); i++)
{
if ((!path.empty() && path.back() > nums[i]) || used[nums[i] + 100])
{
continue;
}
used[nums[i] + 100] = 1;
path.push_back(nums[i]);
backtracking(nums, i + 1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
rst.clear();
path.clear();
backtracking(nums, 0);
return rst;
}
};
46. 全排列
需要有一个used数组来记录已经被使用过的元素索引文章来源:https://www.toymoban.com/news/detail-612872.html
class Solution {
vector<vector<int>> rst;
vector<int> path;
void backtracking(const vector<int> &nums, vector<bool> &used)
{
if (path.size() == nums.size())
{
rst.push_back(path);
return;
}
for (int i = 0; i < nums.size(); ++i)
{
if (used[i]) continue;
used[i] = true;
path.push_back(nums[i]);
backtracking(nums, used);
path.pop_back();
used[i] = false;
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
rst.clear();
path.clear();
vector<bool> used(nums.size(), false);
backtracking(nums, used);
return rst;
}
};
47. 全排列II
还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了。文章来源地址https://www.toymoban.com/news/detail-612872.html
class Solution {
vector<vector<int>> rst;
vector<int> path;
void backtracking(const vector<int> &nums, vector<bool> &used)
{
if (path.size() == nums.size())
{
rst.push_back(path);
return;
}
for (int i = 0; i < nums.size(); ++i)
{
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])
{
continue;
}
if (!used[i])
{
used[i] = true;
path.push_back(nums[i]);
backtracking(nums, used);
path.pop_back();
used[i] = false;
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
rst.clear();
path.clear();
sort(nums.begin(), nums.end());
vector<bool> used(nums.size(), false);
backtracking(nums, used);
return rst;
}
};
到了这里,关于算法刷题Day 29 递增子序列+全排列+全排列II的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!