c++回溯 77、46、784

c++回溯 77、46、784,第1张

c++回溯 77、46、784

今天学习了回溯的算法。

先记录一下模板:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

77. 组合 - 力扣(LeetCode) (leetcode-cn.com)

递归来做层叠嵌套(可以理解是开k层for循环),**每一次的递归中嵌套一个for循环,那么递归就可以用于解决多层嵌套循环的问题了**。

 剪枝优化:

**所以,可以剪枝的地方就在递归中每一层的for循环所选择的起始位置**。

**如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了**。

注意代码中i,就是for循环里选择的起始位置。

for (int i = startIndex; i <= n; i++) {

接下来看一下优化过程如下:

  1. 已经选择的元素个数:path.size();

  2. 还需要的元素个数为: k - path.size();

  3. 在集合n中至多要从该起始位置 : n - (k - path.size()) + 1,开始遍历

为什么有个+1呢,因为包括起始位置,我们要是一个左闭的集合。

class Solution {
public:
vector> result;
    vector path;
    void backtracking(int n, int k, int startIndex) {
        if (path.size() == k) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) { // 优化的地方
            path.push_back(i); // 处理节点
            backtracking(n, k, i + 1);
            path.pop_back(); // 回溯,撤销处理的节点
        }
    }
    vector> combine(int n, int k) {
      backtracking(n, k, 1);
        return result;  
    }
};

 46. 全排列 - 力扣(LeetCode) (leetcode-cn.com)

套模板解题

class Solution {
public:
vector>result;
vectorpath;
void backtracking(vector&nums,int k,vector&vistited){
    if(path.size()==k)
    {
        result.push_back(path);
        return;
    }
    int w=0;
    for(int i=0;i> permute(vector& nums) {
        vectorvistited(nums.size(),false);
        backtracking(nums,nums.size(),vistited);
        return result;
    }
};

 784. 字母大小写全排列 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
private:
    vector result;
public:
    void back(string &s, int i){
        if(i==s.size()){
            result.emplace_back(s);
            return ;
        }
        if(isdigit(s[i])){
            back(s, i+1);
        }
        else{
            s[i]=tolower(s[i]);
            back(s, i+1);

            s[i]=toupper(s[i]);
            back(s, i+1);
        }
    }
    vector letterCasePermutation(string s) {
        back(s, 0);
        return result;
    }
};

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5636179.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存