代码随想录打卡—day24—【回溯】— 基础,最新820 8.21 todo

1 理论基础

  • 回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯算法------回溯和递归是相辅相成的。
  • 回溯法的效率,回溯法其实就是暴力查找,并不是什么高效的算法。
  • 回溯法解决的问题都可以抽象为树形结构(N叉树)

1.1 回溯法,一般可以解决如下几种问题

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

1.2 回溯算法模板框架

cpp 复制代码
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

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

1.3 框架3个stage

  • stage1------回溯函数模板返回值以及参数

在回溯算法中,我的习惯是函数起名字为backtracking,这个起名大家随意。

回溯算法中函数返回值一般为void。再来看一下参数,因为回溯算法需要的参数可不像二叉树递归的时候那么容易一次性确定下来,所以一般是先写逻辑,然后需要什么参数,就填什么参数。

复制代码
void backtracking(参数)
  • stage2------回溯函数终止条件

什么时候达到了终止条件,树中就可以看出,一般来说搜到叶子节点了,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归。

所以回溯函数终止条件伪代码如下:

复制代码
if (终止条件) {
    存放结果;
    return;
}
  • stage3------回溯搜索的遍历过程

回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。

注意图中,我特意举例集合大小和孩子的数量是相等的!

回溯函数遍历过程伪代码如下:

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

大家可以从图中看出for循环可以理解是横向遍历,backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。

2 77. 组合

77. 组合

没看题解,自己第一次写,写是写出来了,但是没有想象的熟练和简洁,AC:

cpp 复制代码
class Solution {
public:
    
    vector<vector<int>> ans;
    bool vis[21];
    int totalk;

    int totaln;

    void dfs(int k,vector<int> tmpans)  // 现在处理第k位
    {
        if(k == totalk)
        {
            ans.push_back(tmpans);
            return;
        }
        int i = tmpans.size() == 0? 1:tmpans[tmpans.size()-1];
        for(; i <= totaln;i++)
        {
            if(!vis[i])
            {
                tmpans.push_back(i);
                vis[i] = 1;
                dfs(k+1,tmpans);
                tmpans.pop_back();
                vis[i] = 0;
            }
        }
    }
    vector<vector<int>> combine(int n, int k) 
    {
        totalk = k;
        totaln = n;
        vector<int> tmpans;
        dfs(0,tmpans);
        return ans;
    }
};

看了题解

821 todo

相关推荐
luj_17685 小时前
残熵算法实时化三大瓶颈突破
c语言·开发语言·网络·经验分享·算法
mCell6 小时前
你以为短链接只是 Hash + 301/302?
后端·算法·架构
KaMeidebaby8 小时前
卡梅德生物技术快报|抗体亲和力成熟工业化调控新机制:差异性浆细胞增殖工艺优化思路
java·开发语言·人工智能·算法·机器学习·架构·spark
luj_17688 小时前
心形曲线轨迹控制三大关键技术
c语言·开发语言·c++·经验分享·算法
tmlx3I0819 小时前
高光谱拼接算法(六)RANSAC 误匹配剔除
人工智能·算法·机器学习
不相心 -w-9 小时前
基础-滑动窗口-(定长 | 不定长)
算法
醉城夜风~9 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法
ysa0510309 小时前
【板子】ST表
c++·笔记·算法·板子
CHHH_HHH10 小时前
【C++11】深入解析C++可变参数模板
开发语言·c++·算法·stl·c++11
hurrycry_小亦10 小时前
洛谷题目:P1215 [USACO1.4] 母亲的牛奶 Mother‘s Milk 题解(本题简)
算法