【Leetcode】NO.77 组合(C++&Python)[回溯]

题目

思路

  1. 组合题目

  2. 由于一个变量的设置错误导致结果成为排列;所以这题的排列和组合两种都可以做

  3. 回溯for循环进行集合大小的遍历

  4. 递归进行深度的遍历
    递归结束条件是当子集大小等于给定的大小的时候将结果加入到结果集合中;
    其次是递归的条件,确定变化的变量

  5. 优化(回溯问进行剪枝)
    // 优化:如果剩下的节点小于所需要的时候进行剪枝
    当前选择的节点数sub.size();共需要的节点数k;剩下的节点数:n-sub.size();还需要的节点数:k-sub.size()
    如果还需要的节点数少于剩余的,直接退出

代码

这题的组合代码

class Solution {
    
public:
    vector<vector<int>> result;
    vector<int> sub;
    void backtrack(int n, int k, int start){
        if(sub.size()==k)
        {
            result.push_back(sub);
            return;
        }

        // 进行for循环
        for(int i=start;i<=n;i++){
            // 放一个节点进来
            sub.push_back(i);
            // 进行递归
            backtrack(n,k,i+1);
            // 回溯
            sub.pop_back();
            
        }
    }
    vector<vector<int>> combine(int n, int k) {

        backtrack(n, k, 1);
        return result;
    }


};

组合问题进行剪枝:

class Solution {
    
public:
    vector<vector<int>> result;
    vector<int> sub;
    void backtrack(int n, int k, int start){
        if(sub.size()==k)
        {
            result.push_back(sub);
            return;
        }
        // 优化:如果剩下的节点小于所需要的时候进行剪枝
        // 当前选择的节点数sub.size();共需要的节点数k;剩下的节点数:n-sub.size();还需要的节点数:k-sub.size()
        // 如果还需要的节点数少于剩余的,直接退出
        // 进行for循环
        for(int i=start;i<=n && k-sub.size()<=n-sub.size();i++){
            // 放一个节点进来
            sub.push_back(i);
            // 进行递归
            backtrack(n,k,i+1);
            
            // 回溯
            sub.pop_back();
            
        }
    }
    vector<vector<int>> combine(int n, int k) {

        backtrack(n, k, 1);
        return result;
    }


};

这题的排列代码:
排列是讲究顺序的(1,2)和(2,1) 是两个不同的组合;

class Solution {
    
public:
    vector<vector<int>> result;
    vector<int> sub;
    void backtrack(int n, int k, int start){
        if(sub.size()==k)
        {
            result.push_back(sub);
            return;
        }

        // 进行for循环
        for(int i=start;i<=n;i++){
            // 放一个节点进来
            sub.push_back(i);
            // 进行递归
            backtrack(n,k,start+1); // 排列只需要改这里i改为start
            // 回溯
            sub.pop_back();
            
        }
    }
    vector<vector<int>> combine(int n, int k) {

        backtrack(n, k, 1);
        return result;
    }


};
posted @ 2022-01-07 16:46  jucw  阅读(29)  评论(0编辑  收藏  举报