leetcode 491. Increasing Subsequences & lc 78. Subsets

来源:互联网 发布:u8用友软件介绍 编辑:程序博客网 时间:2024/04/30 14:54

写在前面

这两题都是关于回溯法的,最近做的题目中遇到的较多,因此把这两个比较有代表性的回溯法题目放在一起写。

leetcode 491 increasing subsequences

题目描述

Given an integer array, your task is to find all the different possible increasing subsequences of the given array, and the length of an increasing subsequence should be at least 2 .

Example:
Input: [4, 6, 7, 7]
Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
Note:
The length of the given array will not exceed 15.
The range of integer in the given array is [-100,100].
The given array may contain duplicates, and two equal integers should also be considered as a special case of increasing sequence.

解题思路

其实看到题目描述就很容易想到回溯法来求解这个问题,我们确定回溯头部,依次遍历数组剩下元素,满足条件的加入到vector中就可以了。
可以发现思路很简单,然后再看看题目要求,其实一个隐含的要求是不能存在重复元素,我们用一个set来解决这个要求,之后再用vector的迭代器构造方式构造出题目要求的vector。
具体代码如下(C++11):

class Solution {public:    vector<vector<int>> findSubsequences(vector<int>& nums) {        set<vector<int>> mSet;        vector<int> mContainer;        for(int i = 0;i<nums.size();++i) {            mContainer.clear();            mContainer.push_back(nums[i]);            backtrack(mSet,mContainer,nums,i);        }        return vector<vector<int>>(mSet.begin(),mSet.end());    }    void backtrack(set<vector<int>>& mSet,vector<int>& mContainer,vector<int>&nums,int start) {        if(mContainer.size()>=2) {            auto tVec=  mContainer;            mSet.insert(tVec);        }        for(int i = start+1;i<nums.size();++i) {            if(nums[i]>=nums[start]) {                mContainer.push_back(nums[i]);                backtrack(mSet,mContainer,nums,i);                mContainer.pop_back();            }        }    }};

leetcode 78 Subsets

题目描述

Given a set of distinct integers, nums, return all possible subsets.

Note: The solution set must not contain duplicate subsets.

For example,
If nums = [1,2,3], a solution is:

[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

解题思路

其实就是求集合的全部子集了,典型的回溯法,直接套模板就可以了,具体实现如下:

class Solution {public:    vector<vector<int>> subsets(vector<int>& nums) {        vector<vector<int>> retVec;        vector<int> vec;        backtrack(retVec,vec,nums,0);        return retVec;    }    void backtrack(vector<vector<int>>& retVec,vector<int> &valueVec,vector<int>& nums,int start) {        vector<int> tmp = valueVec;        retVec.push_back(tmp);        for(int i = start;i<nums.size();++i) {            valueVec.push_back(nums[i]);            backtrack(retVec,valueVec,nums,i+1);            valueVec.pop_back();        }    }};

可以发现这两题的思路是非常相近的,回溯法其实套路也不多,其实就是 加入->回溯->删除 基本方法很容易想到,掌握这种解法就好了。

0 0
原创粉丝点击