代码随想录第24天 | 回溯算法理论、组合

一、前言

参考文献:代码随想录

今天的主题是回溯算法,二叉树章节终于刷过去了,今天的主要任务是了解回溯算法和他的作用,以及模板。

回溯算法的主要作用是解决如下问题:

今天所解决的问题就是组合问题。

回溯是递归的附带品,所以回溯的模板于递归地模板大差不差:

void backtracking(参数)
{
    if (终止条件)
    单层递归和回溯
    return;
}

 模板看着不难,那就让我们来解决今天的题目吧!

二、组合:

1、思路:

看到这个题目,其实就是一个排列问题,所以可以用暴力的方法解决,但是我们并不知道嵌套多少层for循环,因为k(循环次数)是一直变化的,所以我们并不好去暴力,这里就要用到回溯了,也就是在递归里参合着循环。

2、代码如下:

class Solution {
private:
    // 一个是一维数组记录组合,result返回集合
    vector<int> path;
    vector<vector<int>> result;
    // 参数为n,k之外还有起始位置,利用树型结构来抽象推理
    void backTracking (int n, int k, int InStart) {
        // 长度符合终止
        if (path.size() == k) {
            result.push_back(path);
            return;
        } 
        for (int i = InStart; i <= n; i++) {
            path.push_back(i);
            backTracking(n ,k , i + 1);
            // 回溯!,继续给下一次循环使用
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
        backTracking(n ,k , 1);
        return result;
    }
};

在for循环中,我们需要有一个插入和递归的操作,但是其中最重要的是:

path.pop_back();

这是一个回溯的操作,方便后续的组合利用。

3、剪枝:

这里剪枝的操作实质上是一个对代码进行优化的过程,例如:

这就涉及到了时间的浪费,所以需要改变一下,for循环的参数结构 。

看完卡哥的视频后,我其实没有怎么理解,但是有一个公式代替size():

n - (k - path.size()) + 1

这个表示,至多从哪里开始排列,比入n = 4, k = 3,则说明之多可以从2开始排列,234,但是3就不行了。

代码如下:

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(int n, int k, int InStart) {
        if (path.size() == k) {
            result.push_back(path);
            return;
        }

        for (int i = InStart; i <= n - (k - path.size()) + 1; i++) {
            path.push_back(i);
            backtracking(n ,k ,i + 1);
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
        backtracking(n ,k ,1);
        return result;
    }
};

 今日学习时间:1小时;

leave message:

He was still too young to know that the heart's memory eliminates the bad and magnifies the good.

当时他还太年轻,不知道人的内心会删除不好的记忆,放大美好记忆。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值