【高频考点】回溯(暴力搜索)

目录

回溯的目标:是要返回所有符合条件的结果的集合(暴力搜索)

回溯的遍历(类似树的遍历):

​编辑回溯三部曲

1递归函数的返回值以及参数

2回溯函数终止条件

3单层搜索的过程

经典问题

组合问题:N个数里面按一定规则找出k个数的集合

[切割问题:一个字符串按一定规则有几种切割方式 abcdef](#切割问题:一个字符串按一定规则有几种切割方式 abcdef)

子集问题:一个N个数的集合里有多少符合条件的子集

排列问题:N个数按一定规则全排列,有几种排列方式

棋盘问题:N皇后,解数独等等


回溯的目标:是要返回所有符合条件的结果的集合(暴力搜索)

回溯的遍历(类似树的遍历):

for循环-横向遍历-集合大小(树的宽度)

递归-纵向遍历-树的深度

回溯三部曲

1递归函数的返回值以及参数

2回溯函数终止条件

3单层搜索的过程

经典模板:

cpp 复制代码
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
​
    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;   //处理
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果   //还原现场
    }
}

解题技巧:返回值一般是void;先写逻辑再填参数

经典问题

组合问题:N个数里面按一定规则找出k个数的集合

1)写出集合数组 是1,2,3,...,n;画出树结构

2)写回溯函数:①终止条件:长度为k时,加到结果里并返回

②遍历:for范围是集合中元素的个数;

递归的索引是从当前的下一个元素开始(因组合无序)

3)组合数是无序的(用过的不能再用):因此for遍历起始值是当前元素的idx,递归的索引是从当前的下一个元素开始

*如果是多个集合取组合,各个集合之间相互不影响,那么就不用idx

*如果元素是可重复选取的,递归的i的idx不需要+1

*如果集合中元素有重复,但只能用集合中的,就需要用used标记/idx去重;还要先排序sort(candidates.begin(), candidates.end()); 操作的时候加判断是否与上个数字重复

4)定义全局变量:结果数组和中间结果数组

cpp 复制代码
class Solution {
    vector<vector<int>> result;// 存放符合条件结果的集合
    vector<int> temp;// 用来存放符合条件结果
public:
    void backtracking(vector<int> nums, int n, int k,int idx){
        if(temp.size()==k){
            result.push_back(temp);
            return;
        }
        for(int i=idx;i<n;i++){//剪枝优化 i<n-(k-temp.size())+1
            temp.push_back(nums[i]);
            backtracking(nums,n,k,i+1);
            temp.pop_back();
            }  
        }
    vector<vector<int>> combine(int n, int k) {
        vector<int> nums;
        for(int i=0;i<n;i++){
            nums.push_back(i+1);
        }
        backtracking(nums,n,k,0);
        return result;
    }
};

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

切割问题:一个字符串按一定规则有几种切割方式 abcdef

-选取一个a之后,在bcdef中再去选取第2个,选取b之后在cdef中再选取第3个。

-切割一个a之后,在bcdef中再去切割第2段,切割b之后在cdef中再切割第3段。

cpp 复制代码
// 获取[startIndex,i]在s中的子串
string str = s.substr(startIndex, i - startIndex + 1);

子集问题:一个N个数的集合里有多少符合条件的子集

相当于没有终止条件的组合,是统计所有节点(组合是统计所有叶子节点)
*

排列问题:N个数按一定规则全排列,有几种排列方式

每层都是从0开始搜索而不是startIndex

需要used数组记录temp里都放了哪些元素了
*

棋盘问题:N皇后,解数独等等

相关推荐
Gigavision4 小时前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
鹿角片ljp4 小时前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
彧azz5 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
Beyond_System|系统之外6 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
景熙55237 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
汉克老师7 小时前
GESP2026年9月认证C++六级( 第三部分编程题(1、数组划分))精讲
c++·gesp·小学生·学c++编程
千里码aicood8 小时前
基于PLC与机器视觉的智能分拣控制系统设计
c++·自动化·plc
漂流瓶jz8 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
朽棘不雕8 小时前
进一步了解模板
c++
叠层归一研究院9 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi