百度面试题——迷宫问题(超详细解析)

文章目录

  • 一、迷宫问题
    • 1.思路
      • 1.整体思想
      • 2.如何区分走过的路与没有走过的路
      • 3.遇到死路时,如何回溯
    • 2. 整体过程详细分析
    • 2.动态开辟二维数组
    • 3.内存销毁
    • 4.用一个栈转移循环栈中的数据
    • 5. getmazepath(maze, N, M, next)判断是否为真
    • 6. 整体代码


一、迷宫问题

定义一个二维数组 N*M ,如 5 × 5 数组下所示:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

数据范围:2<=nm<=10, 输入的内容只包含 0<=val<=1

1.思路

1.整体思想

迷宫问题的本质是图的遍历问题,从起点开始不断四个方向探索,直到走到出口,走的过程借助栈记录走过的路径,栈记录坐标有两个作用,一方面是记录走过的路径,一方面方便走到死路时进行回溯其他的道路。

2.如何区分走过的路与没有走过的路

当下标为(0,0)的数据找到下方的通路时,达到下标为(1,0)的数据后,才将下标为(0,0)的数据置为2

3.遇到死路时,如何回溯

只有上下左右 四个方向都不可以走时,才进行回溯,回溯到可以继续走的路口

2. 整体过程详细分析

在这里插入图片描述

采用的方向是 上 下 左 右 ,依次寻找,
注意在寻找的过程中每次都需要入栈
为了防止走到死路,进行回溯时无法区分走过的路与没有走过的路,所以将走过的路标记成 2
1.先将下标为(0,0)的数据入栈 ,图1的上面没有数据,去下寻找
2.寻找到了通路0,将下标为(1,0)的数据入栈****同时将走过的(0,0)标记成2
3.在下标为(1,0)时上面为1不能走,下面为0可以走
4.将下标为(2,0)的数据入栈下标为(1,0)的数据置成2,同时判断上 下 左 都不可以走,只能走右边

在这里插入图片描述

5.到达下标(2,1)时发现时死路,此时就需要回溯到可以继续走的路口,当上下左右 都没有路可走时,就销毁栈顶元素,即将在栈中下标为(2,0)的数据销毁,同时回到原路。
6.注意此时的下标(1,0) 只能走左,右两个方向,因为前后方向已经递归回来了!, 走右方向达到下标(1,1)
7.先将下标(1,1)的数据入栈,在判断只有右边可以走。
8.将下标(1,2)的数据入栈将下标(1,1)的数据置成2,在判断(1,2)的数据只有下边可以走。
9.此时的下标(2,2)为出口,再次通过递归出口的位置,此时下标为(0,0)的上下 左右方向都不能走,循环结束 。
此时的栈有先进后出的原则,所以为(2,2) ,(1,2),(1,1),(1,0),(0,0)

2.动态开辟二维数组

假设 N为行 M为列
动态开辟了N个指针数组(数组中的每个元素都为一个指针),
每个指针都指向了一块大小为M的空间

 //动态开辟二维数组int  N=0;//行int  M=0;//列//1.开辟N个指针数组int** maze = (int**)malloc(sizeof(int*) * N);//2.开辟M个空间int i = 0;for (i = 0; i < N; i++){maze[i] = (int*)malloc(sizeof(int) * M);}int j = 0;for (i = 0; i < N; i++){for (j = 0; j < M; j++){scanf("%d", &maze[i][j]);}}

3.内存销毁

1.一定不要直接free(maze) ,此时M个空间都是在每个指针指向后开辟的,并不会销毁。
2.所以要先将M个空间销毁,再将整体N个指针数组销毁

  //释放空间//1.释放N个数组指针指向的空间for (i = 0; i < N; i++){free(maze[i]);}//2.将N个指针数组整体释放free(maze);maze = NULL;

4.用一个栈转移循环栈中的数据

如整体过程的分析,循环栈中为栈有先进后出的原则,所以为(2,2) ,(1,2),(1,1),(1,0),(0,0)
而我们要从入口的下标打印到出口的下标
所以采用在用一个栈,将循环栈中的数据传过来
此时的顺序为 (0,0),(1,0),(1,1),(1,2),(2,2)

void printpath(ST* ps)//由于此时的path栈要打印出来会倒着出,
//所以又重新创建了一个栈,将数据导进去
{ST rpath;stackinit(&rpath);while (!stackempty(&path)){stackpush(&rpath, stacktop(&path));stackpop(&path);}while (!stackempty(&rpath)){PT top = stacktop(&rpath);//此时数据类型被改为PTprintf("(%d,%d)", top.row, top.col);printf("\n");stackpop(&rpath);}stackdestroy(&rpath);//内存销毁
}

5. getmazepath(maze, N, M, next)判断是否为真

若不判断该函数,在回溯时导致重复循环

回溯到下标为(1,0)的地方时,就会导致会重复向下的递归!
从而无限循环下去

ST path;
bool getmazepath(int** maze, int N, int M, PT cur)
{stackpush(&path, cur);//入栈if (cur.row == N - 1 && cur.col == M - 1)//找到出口就返回真{return true;}maze[cur.row][cur.col] = 2;//先将目前所处位置赋值为2PT next;next = cur;//上next.row -= 1;if (ispass(maze, N, M, next))//判断上的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//下next.row += 1;if (ispass(maze, N, M, next))//判断下的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//左next.col -= 1;if (ispass(maze, N, M, next))//判断左的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//右next.col += 1;if (ispass(maze, N, M, next))//判断右的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}stackpop(&path);   //如果上下左右都不满足就移除栈顶元素return false;//如果上下左右都不满足就返回false}

6. 整体代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef struct postion
{int row;//行int col;//列
}PT;
/
typedef PT datatype;//将数据类型改为结构体
typedef struct stack
{datatype* a;int top;int capacity;
}ST;
void stackinit(ST* p);
void stackpush(ST* p, datatype x);
datatype stacktop(ST* p);
void stackpop(ST* p);
int stacksize(ST* p);
bool stackempty(ST* p);
void stackdestroy(ST* p);

void stackinit(ST* p)//栈的初始化
{assert(p);p->a = NULL;p->top = 0;p->capacity = 0;
}
void stackpush(ST* p, datatype x)//入栈
{assert(p);if (p->top == p->capacity){int newcapacity = p->capacity == 0 ? 4 : 2 * p->capacity;datatype* tmp = (datatype*)realloc(p->a, sizeof(datatype) * newcapacity);if (tmp != NULL){p->a = tmp;p->capacity = newcapacity;}}p->a[p->top] = x;p->top++;
}
void stackpop(ST* p)//移除栈顶元素
{assert(p);assert(p->top > 0);p->top--;
}
datatype  stacktop(ST* p)//出栈
{assert(p);assert(p->top > 0);return p->a[p->top - 1];
}
bool  stackempty(ST* p)//是否为空
{return p->top == 0;
}
int stacksize(ST* p)//栈中元素个数
{assert(p);return p->top;
}
void stackdestroy(ST* p)//内存销毁
{assert(p);free(p->a);p->a = NULL;p->top = 0;p->capacity = 0;
}/// ///bool ispass(int** maze, int N, int M, PT pos)
{if (pos.row >= 0 && pos.row < N && pos.col >= 0 && pos.col < M && maze[pos.row][pos.col] == 0){   //坐标不越界并且该处位置==0return true;}return false;
}
ST path;
bool getmazepath(int** maze, int N, int M, PT cur)
{stackpush(&path, cur);//入栈if (cur.row == N - 1 && cur.col == M - 1)//找到出口就返回真{return true;}maze[cur.row][cur.col] = 2;//先将目前所处位置赋值为2PT next;next = cur;//上next.row -= 1;if (ispass(maze, N, M, next))//判断上的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//下next.row += 1;if (ispass(maze, N, M, next))//判断下的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//左next.col -= 1;if (ispass(maze, N, M, next))//判断左的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}next = cur;//右next.col += 1;if (ispass(maze, N, M, next))//判断右的位置是否满足继续的条件{if (getmazepath(maze, N, M, next))//满足条件就递归{return true;//为了防止找到继续递归下去 返回真}}stackpop(&path);   //如果上下左右都不满足就移除栈顶元素return false;//如果上下左右都不满足就返回false}
void printpath(ST* ps)//由于此时的path栈要打印出来会倒着出,
//所以又重新创建了一个栈,将数据导进去
{ST rpath;stackinit(&rpath);while (!stackempty(&path)){stackpush(&rpath, stacktop(&path));stackpop(&path);}while (!stackempty(&rpath)){PT top = stacktop(&rpath);//此时数据类型被改为PTprintf("(%d,%d)", top.row, top.col);printf("\n");stackpop(&rpath);}stackdestroy(&rpath);//内存销毁
}
int main()
{int N = 0;int M = 0;while (scanf("%d%d", &N, &M) != EOF)//多组输入{//动态开辟二维数组//1.开辟N个指针数组int** maze = (int**)malloc(sizeof(int*) * N);//2.开辟M个空间int i = 0;for (i = 0; i < N; i++){maze[i] = (int*)malloc(sizeof(int) * M);}int j = 0;for (i = 0; i < N; i++){for (j = 0; j < M; j++){scanf("%d", &maze[i][j]);}}PT  entry = { 0,0 };stackinit(&path);if (getmazepath(maze, N, M, entry)){printpath(&path);//输出通路的路径}else{printf("没有通路\n");}stackdestroy(&path);//释放空间//1.释放N个数组指针指向的空间for (i = 0; i < N; i++){free(maze[i]);}//2.将N个指针数组整体释放free(maze);maze = NULL;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/70882.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统和强化学习】1.内存管理策略

文章目录 前言1.内存是什么1.1 基本硬件1.1.1 保护措施 1.1.2 碎片1.2 分段机制1.2.1 分段硬件1.3 分页1.4 虚拟存储请求分页储存管理:页面置换方法1.4 程序运行的必要条件1.4.1 链接1.4.2 各种地址 1.5 连续储存管理1.5.1 单一连续分区1.5.2 固定分区1.5.2 可变分区1.5.6 分区…

通过chatGPT学习:kubernetes中的list-watch机制介绍

1、 请解释一下&#xff0c;在kubernetes中的list-watch机制&#xff1f; Kubernetes是一个开源的容器编排和管理系统&#xff0c;它可以有效地管理大规模的容器化应用程序。 在Kubernetes中&#xff0c;list-watch机制是一种重要的机制&#xff0c;用于监视资源的变化并及时…

【chatGPT】让java程序员工作效率翻10倍技巧

本来写给我自己用来着, 想着以后忘记了就分享出来 1.写枚举 对于程序员来说枚举的命名需要大写并且写枚举也是被迫的(大部分人的感受都一样啊喂) 所以可以直接用chatgpt偷懒 录入关键字 : 例:帮我写个java枚举 xxxxx (活动兑奖状态&#xff0c;0待开始&#xff0c;1兑奖中 ,2…

国内晶圆代工现状简析,与国外差距又在哪里?

从去年的科技战开始&#xff0c;美国频频用芯片作为筹码来遏制中国科技产业的发展&#xff0c;使得科技产业不能自主。在这样的大环境下&#xff0c;做大做强自家芯片成为亟不可待的任务。然而&#xff0c;目前中国芯片发展存在诸多困难。在半导体产业链中&#xff0c;中国目前…

芯片全产业链:【设计】-【制造(原材料+制造装备+代工)】-【封装】

http://www.elecfans.com/d/671198.html 国内芯片产业链及主要厂商梳理,芯片的各个细分领域龙头有哪些呢&#xff1f; 1.芯片设计 1.1 芯片设计软件-EDA verilog HDL/传统原理图输入法 关系 HDL和传统原理图输入法的关系就好比高级语言与汇编语言的关系 参考&#xff1a…

芯片供应最难的居然是TI,交期拉长

关注星标公众号&#xff0c;不错过精彩内容 来源 | 芯头条 据台媒报道&#xff0c;全球供应链相当长又复杂&#xff0c;各业者按其所处产业与地位&#xff0c;供需状况其实不同&#xff0c;也就是所面对的缺货、长短料与需求反转的感受不一。但整体来看&#xff0c;随着疫情缓解…

2021年全球晶圆代工营收市占分布预测

原网址&#xff1a; https://xueqiu.com/6828609820/167031894 根据TrendForce集邦咨询旗下半导体研究处表示&#xff0c;2020年上半年全球半导体产业受惠于疫情导致的恐慌性备料&#xff0c;以及远距办公与教学的新生活常态&#xff0c;下半年则因华为禁令的提前拉货&#xf…

晶圆涨、封测涨、芯片涨、材料涨…涨价的野火烧到哪了?

作者&#xff1a;小芯&#xff0c;排版&#xff1a;橡皮 微信公众号&#xff1a;芯世相&#xff08;ID&#xff1a;xinpianlaosiji&#xff09; 继8寸晶圆产能紧缺涨价、半导体元器件上涨、覆铜板等原材料上涨后&#xff0c;由晶圆紧缺引发的“多米诺骨牌”开始逐步蔓延&#x…

涨超10%!国内最大MEMS晶圆代工厂成功上市!市值超400亿!

今日&#xff08;5月10日&#xff09;&#xff0c;中国传感器产业史上又一标志性事件诞生——中国大陆目前规模最大、技术最先进的 MEMS 晶圆代工厂——中芯集成成功上市&#xff01; 本次上市&#xff0c;中芯集成募集资金达百亿&#xff0c;是中国MEMS制造产业慕资规模最大的…

签千亿订单,中芯国际可量产3nm芯片?

本文转载自IT之家&#xff0c;IT之家 3 月 3 日消息 中芯国际发布公告称&#xff0c;公司就购买用于生产晶圆的阿斯麦产品与阿斯麦集团签订购买单&#xff0c;根据阿斯麦购买单购买的阿斯麦产品定价&#xff0c;阿斯麦购买单的总代价为 1201598880 美元。 据介绍&#xff0c;中…

中国12家厂商”逐鹿“国产替代,国产MCU选型合集来了

扫码报名直播领取 MCU厂家选型合集手册.PDF 前言 据统计&#xff0c;整体MCU价格在8月大幅下行后&#xff0c;9月下行趋势减缓&#xff0c;价格下跌型号数量明显减少&#xff0c;整体价格企稳。 在中国市场&#xff0c; 物联网和边缘计算等新兴应用对MCU有着强大的需求&#x…

【电巢】电源管理芯片:国产化替代厂家竞逐千亿黄金赛道

前言 整个2022年三季度&#xff0c;全国新能源电动车的起火已高达600多起&#xff0c;同比上升了30%多&#xff0c;如果具体到每天来看&#xff0c;平均每天都有超过7起新能源电动车火灾发生。 7月22日&#xff0c;台湾省专业赛车手林某颖驾驶着一辆白色特斯拉Model X&#xff…

第六大晶圆代工厂商2021净利润大增593.3%

3月29日&#xff0c;华虹半导体发布2021全年业绩公告&#xff0c;销售收入创历史新高&#xff0c;达16.31亿美元&#xff0c;较上年度增长69.6%&#xff1b;净利润为2.31亿美元&#xff0c;较2020年上升593.3%。 公告指出&#xff0c;华虹半导体销售收入增长因付运晶圆增加及平…

代码恐怖故事:揭秘形成复杂代码库的常见原因

【编者按】本文主要分享一些开发者在软件开发行业中遇到的复杂代码库所带来的问题和挑战。本文列举了造成复杂代码库的常见原因&#xff1a;过分抽象、过度通用化、虚假的测试覆盖、对过时技术的过度热衷、缺乏架构设计、缺少代码版本控制等。文章还强调了管理层对复杂代码块问…

前端使用后端回传的url,显示图片的使用方法

前言 在开发过程中&#xff0c;有时需要动态的添加后端回传的指定url图片。但如果直接使用图片路径充当url&#xff0c;这时就会存在这样一个问题&#xff1a;后端的图片已经变了&#xff0c;但是前端的图片还是原来的。 原因 这是因为浏览器有缓存的功能。如果后端回传的ur…

图片转base64的几种场景(网络图片,本地图片,用户上传图片)

转载于博客园 https://www.cnblogs.com/zhangdiIT/p/7895903.html 写的很棒 推荐给大家 场景一&#xff1a;将用户本地上传的资源转化&#xff0c;即用户通过浏览器点击文件上传时&#xff0c;将图片资源转化成base64&#xff1a; <input type"file" id"im…

C实现响应浏览器HTTP GET请求上传图片

参考链接&#xff1a; 1.C 实现一个简易的Http服务器 https://www.cnblogs.com/life2refuel/p/5277111.html 2.C&#xff1a;C语言实现HTTP的GET和POST请求 https://www.cnblogs.com/diligenceday/p/6255788.html 因为工作需要&#xff0c;需要实现在嵌入式设备上响应浏览器的…

input file 实现上传预览图片,以base64上传,兼容IE8+,firefox,chrome

前言 最近在公司开发一个项目&#xff0c;其中涉及到一个公能&#xff0c;主要是上传一些小图片&#xff0c;而且在网站上需要大量引用这个小图片的&#xff0c;对于上传一些小的头像等。一开始觉得直接上传就好了&#xff0c;但是发现这样子的话&#xff0c;一个小图片就会发…

关于微信内置浏览器,打开图片上传功能,调用的问题

关于微信内置浏览器&#xff0c;打开图片上传功能&#xff0c;调用的问题 前段时间&#xff0c;项目完结测试的时候&#xff0c;同事打开魅族手机测试&#xff0c;无意中发现一个奇葩的问题&#xff01; 描述&#xff1a; 显示的是文件系统&#xff0c;列表式的&#xff0c;没有…

A-Level化学例题解析及练习

今日知识点&#xff1a;Ionisation energy and valence electrons 例题 The table gives the successive ionisation energies for an element X. What could be the formula of the chloride of X A XCl B XCl2 C XCl3 D XCl4 解析 Answer: C Definition of…