全排列、组合、子集问题【DFS+回溯】

1.给出一列互不相同的整数,返回其全排列。
样例

输入:

[1,2,3]

输出:

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

//3个位置,每个位置枚举可以放1,2,3,利用st表示此数是否可用的状态。
class Solution {
public:
    vector<vector<int>> ans;
    vector<bool> st;
    vector<int> temp;
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.size()==0) return vector<vector<int>> {};
        for (int i = 0; i < nums.size(); i ++ ) 
        st.push_back(false);
        dfs(0,nums);
        return ans;
    }
    void dfs(int index,vector<int> nums){
        if(index==nums.size())
        {
            ans.push_back(temp);
            return ;
        }
        for(int i=0;i<nums.size();i++)
        {
            if(st[i]==false)
            {
                st[i]=true;
                temp.push_back(nums[i]);
                dfs(index+1,nums);
                temp.pop_back();
                st[i]=false;
            }
        }

    }
};

2.给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

题解:先用sort函数,进行排序,如果有连续相同的元素,那么相同元素在结果排列中的前后顺序不能改变,就可以达到不出现重复的效果。
在这里插入图片描述

class Solution {
public:

    vector<vector<int>> ans;
    vector<int> temp;
    vector<bool> st;

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        st = vector<bool>(nums.size(), false);
        dfs(nums,0);
        return ans;
    }
    void dfs(vector<int> nums,int index){
        if(index==nums.size())
        {
            ans.push_back(temp);
            return ;
        }
        for(int i=0;i<nums.size();i++)
        {
            if(st[i]==false)
            {
                if(i>0 && nums[i]==nums[i-1] && st[i-1]==false)
                continue;
                st[i]=true;
                temp.push_back(nums[i]);
                dfs(nums,index+1);
                temp.pop_back();
                st[i] = false;
            }
        }
    }
};

3.给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
https://leetcode-cn.com/problems/combinations

题解:利用一个start变量,记录当前进入结果的数的位置,如果是1进入,那么之后的dfs只能从2,3,4中取值。如果是2进入,那么之后的dfs只能从3,4中取值。

class Solution {
public:
    vector<vector<int>> ans;
    vector <int> path;
    vector<vector<int>> combine(int n, int k) {
        dfs(0,1,n,k);
        return ans;
    }
    void dfs(int index,int start,int n,int k){
        if(index == k){
            ans.push_back(path);
            return ;
        }
        for(int i=start;i<=n;i++){
            path.push_back(i);
            dfs(index+1,i+1,n,k);
            path.pop_back();
        }

    }
};

4.给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
链接:https://leetcode-cn.com/problems/subsets

题解:因为是算子集,结果长度不确定,所以不要用index,即枚举每一个位置可以填哪些数。和组合问题类似,也是使用一个start变量,记录当前进入结果的数字,之后的数字只能是此数字之后数字。

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

5.给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。
链接:https://leetcode-cn.com/problems/subsets-ii/

题解:没啥好说的,就是前面的思路叠加。

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    vector<int> st;
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        st=vector<int>(nums.size(),false);
        dfs(nums,0);
        return ans;
    }
    
    void dfs(vector<int>nums,int start ){
        ans.push_back(temp);
        for(int i=start;i<nums.size();i++)
        {
            if(i>0 && nums[i]==nums[i-1] && st[i-1]==false)
            continue;
            else
            {
                st[i]=true;
                temp.push_back(nums[i]);
                dfs(nums,i+1);
                temp.pop_back();
                st[i]=false;
            }
        }
    }
};
发布了13 篇原创文章 · 获赞 0 · 访问量 163

猜你喜欢

转载自blog.csdn.net/qq_43964401/article/details/105425413