版权声明: https://blog.csdn.net/dickdick111/article/details/82756622
题目链接:491. Increasing Subsequences
题目大意:给出一段序列,找出所有递增的子序列,且子序列的长度必须大于等于2.
注意点:
- 序列中可以有重复的元素,而且重复的元素也看作单独的元素,即可出现[3,7,7]这样的子序列。
- 子序列集合中必须进行去重操作,即不能出现[ [3,7],[3,7] ]这样的答案。
- 要利用深度搜索的算法来进行统计
一.算法设计
利用深度搜索算法+集合set去重操作可以实现该题的解答。
我们先从给出序列的第一个元素进行深度搜索,当子序列中为空或者搜索出来的数大于等于子序列的最后一个元素,将该元素放进子序列,然后继续深度搜索。
每次搜索之前,对子序列的长度进行判断,当子序列的长度大于等于2,将这样的子序列放入临时集合中,作为输出答案。
二.实现代码
class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
set<vector<int>> s; //利用集合来做去重操作
vector<vector<int>> v;
vector<int> temp; //储存满足条件的序列
int start = 0; //从第一个数开始深度搜索
dfs(nums,s,temp,start);
v = vector<vector<int>>(s.begin(),s.end()); //将集合中的值赋值回v并返回
return v;
}
void dfs(vector<int> &nums, set<vector<int>> &s, vector<int> &temp, int start){
if (temp.size() >= 2) s.insert(temp); //判断子序列长度是否大于等于2
for(int i = start; i < nums.size(); i++){
if(temp.size() == 0 || nums[i] >= temp.back()){ //当子序列为空或者搜索出来的结果大于等于子序列最后一个数
temp.push_back(nums[i]);
dfs(nums,s,temp,i+1); //继续对i+1开始进行深度搜索
temp.pop_back();
}
}
return;
}
};
三.改进方法
上述的方法是利用将所有元素都放进集合的方法来去重,这样有些重复的子序列是根本不用考虑,减少这些子序列就可以减少搜索的次数,从而降低时间复杂度。
我们可以利用集合s,在每一次将元素pop_back后,将该元素放进集合s。而且在判断是否进行dfs的条件中添加搜索的元素必须不在该集合当中,否则搜索下一个元素。
if(s.find(nums[i]) != s.end()) continue; //新添加
class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<vector<int>> v;
vector<int> temp; //储存满足条件的序列
int start = 0; //从第一个数开始深度搜索
dfs(nums,v,temp,start);
return v;
}
void dfs(vector<int> &nums, vector<vector<int>> &v, vector<int> &temp, int start){
set<int> s; //将搜索过的数放入该集合
if (temp.size() >= 2) v.push_back(temp); //判断子序列长度是否大于等于2
for(int i = start; i < nums.size(); i++){
if(s.find(nums[i]) != s.end()) continue;
if(temp.size() == 0 || nums[i] >= temp.back()){ //当子序列为空或者搜索出来的结果大于等于子序列最后一个数
temp.push_back(nums[i]);
s.insert(nums[i]);
dfs(nums,v,temp,i+1); //继续对i+1开始进行深度搜索
temp.pop_back();
}
}
return;
}
};