当前位置: 首页 > news >正文

力扣P1706全排列问题 很好的引入暴力 递归 回溯 dfs

 代码思路是受一个洛谷题解里面大佬的启发。应该算是一个dfs和回溯的入门题目,很好的入门题目了下面我会先给我原题解思路我想可以很快了解这个思路。下面是我自己根据力扣大佬写的。

我会进行详细讲解并配上图辅助理解大家请往下看

#include<iostream>
#include<iomanip>
using namespace std;
int n,k;
int a[100], b[100];
void print(int n)
{for (int i = 1; i <= n; i++) {cout <<setw(5)<< a[i];}cout << endl;return;
}
void dfs(int k) {if (k == n) {print(n);return;}for (int i = 1; i <= n; i++) {if (!b[i]) {b[i] = 1;a[k + 1] = i;dfs(k + 1);b[i] = 0;}}
}
int main()
{cin >> n;dfs(0);return 0;
}

这是原题解的原代码

#include<bits/stdc++.h>
using namespace std;
int n,pd[100],used[100];//pd是判断是否用过这个数
void print()//输出函数
{int i;for(i=1;i<=n;i++)printf("%5d",used[i]);//保留五位常宽cout<<endl;
}
void dfs(int k)//深搜函数,当前是第k格
{int i;if(k==n) //填满了的时候{print();//输出当前解return;}for(i=1;i<=n;i++)//1-n循环填数{if(!pd[i])//如果当前数没有用过{pd[i]=1;//标记一下used[k+1]=i;//把这个数填入数组dfs(k+1);//填下一个pd[i]=0;//回溯}}
}
int main()
{cin>>n;dfs(0);//注意,这里是从第0格开始的!return 0;
}

我一开始卡住的点是这里也是代码最最最核心的地方。我非常迷糊这里面有回溯

pd[i]=0;//回溯

然后又是for循环,之后又是dfs(k+1)很明显这是递归。我不知道程序运行的顺序是什么给我绕懵逼了,昨天晚上想了一晚上。咪咪咪咪咪。

for(i=1;i<=n;i++)//1-n循环填数{if(!pd[i])//如果当前数没有用过{pd[i]=1;//标记一下used[k+1]=i;//把这个数填入数组dfs(k+1);//填下一个pd[i]=0;//回溯}}
}

重点思路总结:递归这个顺序比for循环的优先级高。通过dfs不断增加就是层数增加并且在dfs(k+1)同时进行了标记和used【K+1】计入数组,避免重复和数组填入类似剪枝和遍历,并且到达最大层数时返回并print输入结果之后回溯dfs()应为刚开始不是加到最大层数吗执行完后返回当初的dfs(2)(这里回溯其实是函数递归调用)继续循环。直到遍历所有。很巧妙,会用就行。

思路来源思考过程

刚开始我困惑于递归这个顺序和for循环的优先级。

我用gtp作图然后又去北理工acmb站视频看了看。之后就是递归就是递推加回溯但是这个应该是计算机原理导致的。理解的话就是机器就是这样运作的,有什么调用帧啥玩意的。

如果打比方就是你可以想一想这个猴子偷桃问题,原题就是有10天每天吃二分之一+1(真能吃啊)问原来多少桃子。你把递归式子列出来然后计算机就会一个递推(形容一下你能知道我在说什么就行)到第1天吧好像是然后在回溯一直回溯然后算出结果。

其实讲到这里会的早就能听懂了。然后为了更直观大家理解我放几个图大家自行观看哈。

上面这个照片大家主要看图还有上面那几段话我觉得很好嗯说的就很好 

上面这个图看看图就行我截的片段

下面的两个图是gpt辅助理解的流程大家可自行阅读理解

import pandas as pd# Data for each step of dfs for n = 3
data = [{"Step": "dfs(0)", "k": 0, "used": [None, None, None], "pd": [0, 0, 0], "Action": "Start dfs(0)"},{"Step": "dfs(0)", "k": 0, "used": [1, None, None], "pd": [1, 0, 0], "Action": "i=1, place 1, recurse dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [1, 2, None], "pd": [1, 1, 0], "Action": "i=2, place 2, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [1, 2, 3], "pd": [1, 1, 1], "Action": "i=3, place 3, recurse dfs(3)"},{"Step": "dfs(3)", "k": 3, "used": [1, 2, 3], "pd": [1, 1, 1], "Action": "Print {1, 2, 3}, backtrack to dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [1, 2, None], "pd": [1, 1, 0], "Action": "Unmark i=3, backtrack to dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [1, None, None], "pd": [1, 0, 0], "Action": "Unmark i=2, try i=3"},{"Step": "dfs(1)", "k": 1, "used": [1, 3, None], "pd": [1, 0, 1], "Action": "i=3, place 3, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [1, 3, 2], "pd": [1, 1, 1], "Action": "i=2, place 2, recurse dfs(3)"},{"Step": "dfs(3)", "k": 3, "used": [1, 3, 2], "pd": [1, 1, 1], "Action": "Print {1, 3, 2}, backtrack to dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [1, 3, None], "pd": [1, 0, 1], "Action": "Unmark i=2, backtrack to dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [1, None, None], "pd": [1, 0, 0], "Action": "Unmark i=3, backtrack to dfs(0)"},{"Step": "dfs(0)", "k": 0, "used": [None, None, None], "pd": [0, 0, 0], "Action": "Unmark i=1, try i=2"},{"Step": "dfs(0)", "k": 0, "used": [2, None, None], "pd": [0, 1, 0], "Action": "i=2, place 2, recurse dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [2, 1, None], "pd": [1, 1, 0], "Action": "i=1, place 1, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [2, 1, 3], "pd": [1, 1, 1], "Action": "i=3, place 3, recurse dfs(3)"},{"Step": "dfs(3)", "k": 3, "used": [2, 1, 3], "pd": [1, 1, 1], "Action": "Print {2, 1, 3}, backtrack to dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [2, 1, None], "pd": [1, 1, 0], "Action": "Unmark i=3, backtrack to dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [2, None, None], "pd": [0, 1, 0], "Action": "Unmark i=1, try i=3"},{"Step": "dfs(1)", "k": 1, "used": [2, 3, None], "pd": [0, 1, 1], "Action": "i=3, place 3, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [2, 3, 1], "pd": [1, 1, 1], "Action": "i=1, place 1, recurse dfs(3)"},{"Step": "dfs(3)", "k": 3, "used": [2, 3, 1], "pd": [1, 1, 1], "Action": "Print {2, 3, 1}, backtrack to dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [2, 3, None], "pd": [0, 1, 1], "Action": "Unmark i=1, backtrack to dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [2, None, None], "pd": [0, 1, 0], "Action": "Unmark i=3, backtrack to dfs(0)"},{"Step": "dfs(0)", "k": 0, "used": [None, None, None], "pd": [0, 0, 0], "Action": "Unmark i=2, try i=3"},{"Step": "dfs(0)", "k": 0, "used": [3, None, None], "pd": [0, 0, 1], "Action": "i=3, place 3, recurse dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [3, 1, None], "pd": [1, 0, 1], "Action": "i=1, place 1, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [3, 1, 2], "pd": [1, 1, 1], "Action": "i=2, place 2, recurse dfs(3)"},{"Step": "dfs(3)", "k": 3, "used": [3, 1, 2], "pd": [1, 1, 1], "Action": "Print {3, 1, 2}, backtrack to dfs(2)"},{"Step": "dfs(2)", "k": 2, "used": [3, 1, None], "pd": [1, 0, 1], "Action": "Unmark i=2, backtrack to dfs(1)"},{"Step": "dfs(1)", "k": 1, "used": [3, None, None], "pd": [0, 0, 1], "Action": "Unmark i=1, try i=2"},{"Step": "dfs(1)", "k": 1, "used": [3, 2, None], "pd": [0, 1, 1], "Action": "i=2, place 2, recurse dfs(2)"},{"Step": "dfs(2)", "k": 2

感谢观看谢谢谢谢么么么么~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Docker 的安装部署与基本使用
  • 使用 from __future__ import annotations 语句来允许在类型注释中使用尚未定义的类名
  • 用 Pygame 实现一个乒乓球游戏
  • 数字IC设计\FPGA 职位经典笔试面试整理--语法篇 Verilog System Verilog(部分)
  • lxml库
  • Axios基本语法和前后端交互
  • 【排序算法】选择排序、堆排序
  • Vue3:shallowRef与shallowReactive
  • JS手写Promise以及promise.all方法
  • 【算法】贪心+堆排序实现大根堆及标准库容器类的融合使用
  • 车载网络测试实操源码_使用CAPL脚本实现安全访问解锁,并模拟各种测试场景
  • C语言中易混淆概念的关键字
  • Qt/C++ 多线程同步机制详解及应用
  • redis 十大应用场景
  • 特种作业管理系统 —— 企业安全与效率的卓越保障
  • python3.6+scrapy+mysql 爬虫实战
  • 10个最佳ES6特性 ES7与ES8的特性
  • Angular 4.x 动态创建组件
  • dva中组件的懒加载
  • Facebook AccountKit 接入的坑点
  • GitUp, 你不可错过的秀外慧中的git工具
  • JavaScript 一些 DOM 的知识点
  • JS+CSS实现数字滚动
  • react-native 安卓真机环境搭建
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • WebSocket使用
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 基于axios的vue插件,让http请求更简单
  • 聚簇索引和非聚簇索引
  • 入门级的git使用指北
  • 深度解析利用ES6进行Promise封装总结
  • 新手搭建网站的主要流程
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 7行Python代码的人脸识别
  • kubernetes资源对象--ingress
  • 如何在招聘中考核.NET架构师
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #git 撤消对文件的更改
  • (2015)JS ES6 必知的十个 特性
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (三分钟)速览传统边缘检测算子
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (四)opengl函数加载和错误处理
  • (一)Dubbo快速入门、介绍、使用
  • (一)RocketMQ初步认识
  • .h头文件 .lib动态链接库文件 .dll 动态链接库