算法专辑5:回溯算法

回溯算法
剑指Offer P88

1.基础知识

强烈推荐labuladong同学的题解
1- 回溯算法通常也不具有返回值,和dfs很像。可以将输入设置为全局变量,然后回溯函数的输入大概包括
backTrack(当前路径,选择列表)
2- backTrack 函数
2-1 判断截止条件,如果满足条件,则将当前结果路径压入结果
2-2 对于选择列表中的每一个可行选项
做选择,
backTrack(更新选择路径,更新选择列表);
撤销路径(因为在循环内,撤销刚才尝试,然后尝试当前路径中的下一个可行选项)

# 回溯算法伪代码
result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    
    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择

另附最近看过的某位大神的讲解,感觉讲的不错。👇
dfs讲解
其中,对于全排列这种问题,可以使用一个与输入等长数组vector<bool>来存储当前的路径。

2.例题

2.1 矩阵中的路径

2.2 机器人的运动范围

2.3 括号生成

在这里插入图片描述

解题思路:想好递归数,如递减树,记录剩余的左右括号可使用的个数。
当没有左右括号可以使用时,将此时的字符串输出,否则只有当可用的右括号不少于左括号时,才可以加入左括号,并递归;否则,可以加入右括号,并递归。

对Backtrack算法和DFS算法不够熟练,此题当做课后作业了。请补足代码于下方:

// backtrack

2.4 全排列

在这里插入图片描述

2.5 组合

套用模板!!

    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> res;
        vector<int> valid_res;
        count(res, valid_res, n, k, 1);
        return res;
    }

    void count(vector<vector<int>> &res, vector<int> &valid_res, int &n, int &k, int idx){
        if(valid_res.size() >= k){
            res.push_back(valid_res);
            return;
        }else{
            for(int i = idx; i <= n; ++i){
                valid_res.push_back(i);
                count(res, valid_res, n, k, i+1);
                valid_res.pop_back();
            }
        }
    }

下面为英文解答的神来之笔!

vector<vector<int>> combine(int n, int k) {
    vector<vector<int>> a;
    vector<int> b(k,0);
    int i=0;
    while (i >= 0)
    {
        b[i]++;
        if (b[i] > n) i--;
        else if (i == k - 1) a.push_back(b);
        else
        {
            i++;
            b[i] = b[i - 1];
        }
    }
    return a;
}

3.必会例题

3.1 N皇后问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值