[leetcode]回溯法
零.参考视频!安利!!!
带你学透回溯算法(理论篇)| 回溯法精讲!_哔哩哔哩_bilibili
一.回溯法可以解决的问题
1.排列
2.组合
3.分割
4.子集
5.棋盘
二.回溯法的模板

我的理解:
1.首先命名函数名为backtracking
2.按需求放入需要的参数
3.回溯算法是离不开递归的,而递归算法必要的就是它的退出条件
if(终止条件)
{
收集结果
return;
}
4.处理完这一层的数据之后,我们要处理下面的节点
for(节点元素)
{
处理节点
5.处理完当前节点后需要递归到下一层
for(节点元素)
{
处理节点
递归函数
6.我们找寻找我们需要的结果的时候,遇到需要回溯的情形了,我们要进行对应的回溯
for(节点元素)
{
处理节点
递归函数
回溯操作
}
vector<> res; // 用于存放最后结果
 vector<> path; // 用于存放每一次最外层 for 循环产生的结果
 void backtracking(参1:题目中的数组,参2:结束循环的变量,参3:第n层 for 循环从谁开始,也就是子数组的开始位置,是一直变化的) { // 参数中要有一个值控制树的深度
     if (终止条件) { 
         // 这里控制 for 循环是几重 for 循环,并返回上一层 for 循环
         存放结果; // 将哪些变量添加到 res 
         return;
     }
    for (int i = 子数组在哪开始;i<要对哪些数进行遍历,并进行相关剪枝操作;i++) {  // 控制最外层 for 循环递归多少次
         // TODO 该元素在 push 之前的相关操作
         path.push_back(i); // 将 i 添加到 path 中
         backtracking(参1:题目中的数组,参2:结束循环的变量,参3:第n层 for 循环从谁开始); // 递归
         // TODO 该元素在弹出之前的相关操作
         path.pop_back();
     }
 }
 三.具体问题
 
问题:全排列问题
问题描述
 给定一个整数 n,生成由 1 到 n 组成的所有不重复的数字序列,每行一个序列,每个数字保留 5 个场宽。
输入输出样例
-  输入: 3
-  输出: 复制 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
解题思路
这是一个典型的全排列问题,可以通过回溯法解决。具体步骤如下:
-  使用深度优先搜索(DFS)逐步构建排列。 
-  使用一个标记数组 hx来记录每个数字是否已经被使用,避免重复选择。
-  在递归过程中,每次选择一个未使用的数字加入当前排列,并递归调用。 
-  递归返回后,取消标记,以便尝试其他可能的排列。 
Coding:蓝桥杯模板:排列型模板
//生成从1到n的全排列

Coding:
#include<iostream>
using namespace std;
int n;//共计n个数
 int order[20];
 bool chosen[20];
void calc(int k)//生成从 1 到 n 的所有全排列
 {
     if (k == n + 1)//递归终止条件
     {
         for (int i = 1;i <= n;i++)
         {
             cout << order[i] << "";
         }
         puts("");
         return;
     }
     for (int i = 1;i <= n;i++)//尝试所有可能的数字
     {
         if (chosen[i])//检查数字是否已被使用
         {
             continue;
         }
         order[k] = i;//选择数字并标记
         chosen[i] = 1;
         calc(k + 1);//递归生成下一个位置的排列
         chosen[i] = 0;//回溯操作
         order[k] = 0;
     }
 }
int main()
 {
     // 从用户输入中读取 n 的值
     cout << "请输入 n 的值: ";
     cin >> n;
     // 从第一个位置开始生成排列
     calc(1);
     return 0;
 }
