题目:
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是 2 。
/*
这道题对比前面的题,有两处需要注意的:
1、这题是不能对给定数组排序的,因为是要求找给定数组的顺序找其子序列,既然是子序列那顺序就不能变
2、既然不能排序,那么相同的元素就不一定是挨着的,所以,就不能是相邻元素做比较,就要用哈希映射每个元素是否取过
set 的一个没见过的用法
uset.find(nums[i] != uset.end())
vector 的一个没见过的用法
path.back()
// 错误代码记录 这个是在回溯函数中的
if(path.size() > 1)
{
// for(int i = 0; i < path.size()-1;i++)
// {
// if(path[i] > path[i+1])
// {
// return;
// }
// }
// 1、这里的逻辑在for循环里取了
// 2、这里不写 ruturn
result.push_back(path);
}
// // 其实这个等号,还是有点萌萌哒~~~~
// 这里的终止条件完全可以不要的,因为在for循环中,当到达最后一位时自然会终止滴
// if(startIndex == nums.size())
// {
// return;
// }
*/
// 法一::用 unordered_map 实现 哈希映射
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int startIndex)
{
if(path.size() > 1)
{
result.push_back(path);
}
// 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
unordered_map<int, int> mp; // key=元素值 value = 出现次数,如果出现次数大于1,则说明重复
for(int i = startIndex; i < nums.size(); ++i)
{
// 判断是否是递增的逻辑放在了这里来处理
// 树层去重的逻辑也在这里
// 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
/***啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊阿啊啊啊*/
// 这里想明白 if语句中的(mp[nums[i]] > 1 )这个条件和 mp[nums[i]]++; 放在 if 前还是放 if 后的关系了
// 以下的两种写法都是对哒!!!棒棒哒~
// 写法一:::
// mp[nums[i]]++;
// if((mp[nums[i]] > 1 ) || (!path.empty() && nums[i] < path.back()))
// {
// continue;
// }
// path.push_back(nums[i]);
// backtracking(nums, i + 1);
// path.pop_back();
// 写法二::::
if((mp[nums[i]] == 1 ) || (!path.empty() && nums[i] < path.back()))
{
continue;
}
mp[nums[i]]++;
path.push_back(nums[i]);
backtracking(nums, i + 1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums)
{
path.clear();
result.clear();
backtracking(nums, 0);
return result;
}
};
// // 法二::用 unordered_set 实现哈希映射
// // path.back()
// // uset.find(nums[i] != uset.end())
// class Solution {
// private:
// vector<int> path;
// vector<vector<int>> result;
// void backtracking(vector<int>& nums, int startIndex)
// {
// if(path.size() > 1)
// {
// result.push_back(path);
// }
// // 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
// unordered_set<int> uset; // 使用uset记录出现过的元素
// for(int i = startIndex; i < nums.size(); ++i)
// {
// // 判断是否是递增的逻辑放在了这里来处理
// // 树层去重的逻辑也在这里
// // 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
// if((uset.find(nums[i]) != uset.end()) || (!path.empty() && nums[i] < path.back()))
// {
// continue;
// }
// uset.insert(nums[i]); // 记录这个元素在本层用过了,本层后面不能再用
// path.push_back(nums[i]);
// backtracking(nums, i + 1);
// path.pop_back();
// }
// }
// public:
// vector<vector<int>> findSubsequences(vector<int>& nums)
// {
// path.clear();
// result.clear();
// backtracking(nums, 0);
// return result;
// }
// };
// // 法三::用 数组 实现 哈希映射
// // 因为本题说明了数值的范围是 [-100, 100],所以完全可以用数组来做哈希
// class Solution {
// private:
// vector<int> path;
// vector<vector<int>> result;
// void backtracking(vector<int>& nums, int startIndex)
// {
// if(path.size() > 1)
// {
// result.push_back(path);
// }
// // 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
// int used[201] = {0}; // 定义一个大小为 201 的数组,并将其均初始化为 0 ,
// for(int i = startIndex; i < nums.size(); ++i)
// {
// // 判断是否是递增的逻辑放在了这里来处理
// // 树层去重的逻辑也在这里
// // 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
// if((used[nums[i] + 100 ]== 1) || (!path.empty() && nums[i] < path.back()))
// {
// continue;
// }
// // 因为元素的范围是 [-100, 100],所以将其映射到 [0 , 200],如果出现过,则将对应位置上赋值为1
// 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)
// {
// path.clear();
// result.clear();
// backtracking(nums, 0);
// return result;
// }
// };