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

力扣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

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


http://www.kler.cn/a/318860.html

相关文章:

  • 企业一站式管理系统odoo的研究——PLM插件的搭建
  • Python 中.title()函数和.lower()函数
  • 2411d,右值与移动
  • PyTorch深度学习与企业级项目实战-预训练语言模型GPT
  • 基于Python的网上银行综合管理系统
  • 界面控件Kendo UI for Angular中文教程:如何构建带图表的仪表板?(一)
  • 2024年及未来:构筑防御通胀的堡垒,保护您的投资
  • XXl-SSO分布式单点登录框架
  • 记录一次学习--kerberos协议学习以及一些攻击手法
  • 【Java】虚拟机(JVM)内存模型全解析
  • PostgreSQL运用关键点是什么呢?
  • RL进阶(一):变分推断、生成模型、SAC
  • ESXI主机加入VCENTER现有集群提示出现常规性错误
  • Vue 自定义指令实现权限控制
  • Redis哨兵详细理论实操教程
  • UE4_后期处理七—仿红外线成像效果
  • 配置Docker镜像加速器
  • 一个10k stars开源的证件照工具
  • 【Go语言】Go语言结构体全面解析
  • 9.24-k8s服务发布
  • C#|.net core 基础 - 深拷贝的五大类N种实现方式
  • streamlit 文件上传保存+预览
  • 七层负载均衡和四层负载均衡的区别
  • 苍穹外卖学习笔记(十一)
  • 智谱AI:CogVideoX-2b——视频生成模型的得力工具
  • 短视频矩阵源码/短视频矩阵系统搭建/源码开发知识分享