Day 29 回溯算法
491. 遞增子序列
如果直接像下面這樣寫的話,會出錯,出錯的案例類似:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(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;
}
};
本題求自增子序列,是不能對原數(shù)組進行排序的,排完序的數(shù)組都是自增子序列了。
所以不能使用之前的去重邏輯!
同一父節(jié)點下的同層上使用過的元素就不能再使用了
正確的寫法如下:
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數(shù)組來記錄已經(jīng)被使用過的元素索引文章來源:http://www.zghlxwxcb.cn/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
還要強調(diào)的是去重一定要對元素進行排序,這樣我們才方便通過相鄰的節(jié)點來判斷是否重復使用了。文章來源地址http://www.zghlxwxcb.cn/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的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!