深度优先搜索(dfs)--矩阵部分-leetcode以及常见题

介绍

深度优先搜索(Depth-First Search,DFS)是一种常用的图搜索算法,它用于查找图或树数据结构中的路径或解决问题。下面是深度优先搜索的常见步骤以及一个示例问题:

深度优先搜索的常见步骤:

  1. 选择起始节点:首先,选择一个起始节点,从该节点开始搜索。

  2. 访问节点:访问当前节点,并标记它为已访问。这可以通过将节点标记为已访问或将其添加到访问过的节点列表中来实现。

  3. 探索相邻节点:从当前节点出发,探索其相邻节点。这可以通过遍历与当前节点相连接的边或邻接节点来实现。

  4. 递归或栈:对于每个相邻节点,如果它还没有被访问过,就递归地或使用栈将其作为当前节点进行访问。这是深度优先搜索的关键部分,它会一直沿着一个路径深入,直到达到叶子节点或无法继续深入为止。

  5. 回溯:当无法继续深入时,回溯到上一个节点,并尝试探索其他相邻节点,直到找到解决方案或访问完所有节点。

  6. 重复步骤3至步骤5:重复步骤3至步骤5,直到找到问题的解决方案或访问了所有可达节点。

简单的例子

        

#include <iostream>
#include <vector>using namespace std;// 定义图的节点结构
struct Node {int val;vector<Node*> neighbors;bool visited;Node(int _val) : val(_val), visited(false) {}
};// 深度优先搜索函数
bool dfs(Node* current, Node* target, vector<Node*>& path) {if (current == target) {path.push_back(current);return true;}current->visited = true;path.push_back(current);for (Node* neighbor : current->neighbors) {if (!neighbor->visited) {if (dfs(neighbor, target, path)) {return true;}}}// 如果无法找到路径,回溯path.pop_back();return false;
}int main() {// 创建节点Node* A = new Node(1);Node* B = new Node(2);Node* C = new Node(3);Node* D = new Node(4);// 构建图的连接关系A->neighbors.push_back(B);A->neighbors.push_back(C);B->neighbors.push_back(D);C->neighbors.push_back(D);// 初始化路径vector<Node*> path;// 执行深度优先搜索bool foundPath = dfs(A, D, path);// 输出结果if (foundPath) {cout << "Path from A to D found:" << endl;for (Node* node : path) {cout << node->val << " ";}cout << endl;} else {cout << "Path from A to D not found." << endl;}// 释放节点内存delete A;delete B;delete C;delete D;return 0;
}
/*
在这个示例中,我们首先定义了一个表示图节点的结构体Node,每个节点具有一个值、一个标记用于表示是否已访问和一个邻接节点的列表。然后,我们实现了一个深度优先搜索函数dfs,该函数递归地探索图中的节点,同时维护一个路径列表。如果找到从起始节点到目标节点的路径,它将返回true,并在路径列表中存储找到的路径。在main函数中,我们创建了图的节点并构建了节点之间的连接关系。然后,我们调用dfs函数来查找从节点A到节点D的路径,并输出结果。如果路径存在,它将打印出路径上的节点值,否则会显示未找到路径。最后,我们释放了节点的内存以避免内存泄漏。
*/

题目1:华为机试题43 迷宫问题。

地址 迷宫问题_牛客题霸_牛客网

题目描述:

定义一个二维数组 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≤n,m≤10  , 输入的内容只包含

0≤val≤1

输入描述:

输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输入:

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

复制

输出:

(0,0)

(1,0)

(2,0)

(2,1)

(2,2)

(2,3)

(2,4)

(3,4)

(4,4)

复制

示例2

输入:

5 5

0 1 0 0 0

0 1 0 1 0

0 0 0 0 1

0 1 1 1 0

0 0 0 0 0

复制

输出:

(0,0)

(1,0)

(2,0)

(3,0)

(4,0)

(4,1)

(4,2)

(4,3)

(4,4)

复制

说明:

注意:不能斜着走!!


#include <iostream>
#include<vector>
using namespace std;vector<vector<int> > res;
bool dfs(vector<vector<int>>& v, int m, int n, int i, int j) {if (i == m - 1 && j == n - 1) {res.push_back({i, j});return true;}//通过这个false 判定这个结果。if (i < 0 || i >= m || j < 0 || j >= n || v[i][j] == -1 || v[i][j] == 1) {return false;}v[i][j] = -1;res.push_back({i, j});if (dfs(v, m, n, i - 1, j) || dfs(v, m, n, i + 1, j) ||dfs(v, m, n, i, j - 1) || dfs(v, m, n, i, j + 1)) {return true;}res.pop_back();v[i][j] = 0;return false;}int main() {int m, n;int temp;cin >> m >> n;vector<vector<int> > v(m, vector<int>(n, 0));for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {cin >> v[i][j];}}dfs(v,m,n,0,0);for(const auto & x:res){// printf("(%d,%d)\n",x[0],[1]);// printf("(%d,%d) \n",x[0],[1]);printf("(%d,%d)\n", x[0], x[1]);}return 0;}

题目2:剑指offer12 矩阵中的路径

链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

 

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
class Solution6 {
public:bool dfs(vector<vector<char>>& board,string word,int i,int j,int k,vector<vector<int>> &path){if(i<0||i>=board.size()||j<0||j>=board[0].size()||path[i][j]==1){return false;}if(board[i][j]==word[k]&&k==word.size()-1){return true;}if(word[k]==board[i][j]){path[i][j]=1;if(dfs(board,word,i+1,j,k+1,path)||dfs(board,word,i-1,j,k+1,path)||dfs(board,word,i,j-1,k+1,path)||dfs(board,word,i,j+1,k+1,path)){return true;}}path[i][j]=0;return false;}bool exist(vector<vector<char>>& board, string word) {int m=board.size();int n=board[0].size();bool res=false;vector<vector<int> > path(m,vector<int>(n,0));for(int i=0;i<m;i++){for(int j=0;j<n;j++){res = dfs(board, word, i, j, 0, path);if(res){//i,j 是起点只要有一个七点满足条件就可以return true;}}}return  res;}};int main()
{Solution6 s;vector<vector<char>> board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};// vector< vector<char> > board={}string word = "ABCCED";bool res = s.exist(board, word);cout << res << endl;system("pause");return 0;
}

题目3 leetcode 200岛屿的数量 

leet200 岛屿的数量 https://leetcode.cn/problems/number-of-islands/

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [

  ["1","1","1","1","0"],

  ["1","1","0","1","0"],

  ["1","1","0","0","0"],

  ["0","0","0","0","0"]

]

输出:1

示例 2:

输入:grid = [

  ["1","1","0","0","0"],

  ["1","1","0","0","0"],

  ["0","0","1","0","0"],

  ["0","0","0","1","1"]

]

//可以这么理解,(遍历整个岛屿的元素,如果是1就对这个点的值进行深度优先搜索,将相邻的全部改成0) 岛屿的数量+1。

class Solution7
{
public:int n;void dfs(vector<vector<char>> &grid, int i, int j, int m, int n){if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0'){return;}grid[i][j] = '0';dfs(grid, i - 1, j, m, n);dfs(grid, i + 1, j, m, n);dfs(grid, i, j - 1, m, n);dfs(grid, i, j + 1, m, n);return;}int numIslands(vector<vector<char>> &grid){int m = grid.size();int n = grid[0].size();int num = 0;// vector<vector<bool> > path=vector(m,vector<int>(n,0));for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){if (grid[i][j] == '1'){n++;dfs(grid, i, j, m, n);}}}return n;}
};int main()
{Solution7 s7;vector<vector<char>> gird = {{'1'}, {'1'}};auto res = s7.numIslands(gird);cout << res << endl;system("pause");return 0;
}

=================================后续待补=================================

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

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

相关文章

Layui快速入门之第一节Layui的基本使用

目录 一&#xff1a;Layui的基本概念 二&#xff1a;Layui使用的基本步骤 1.在官网下载layui的基本文件&#xff0c;引入css和js文件 ①&#xff1a;普通方式引入 ②&#xff1a;第三方 CDN 方式引入 2.在script标签体中编写代码 3.测试 一&#xff1a;Layui的基本概念 …

flink学习之广播流与合流操作demo

广播流是什么&#xff1f; 将一条数据广播到所有的节点。使用 dataStream.broadCast() 广播流使用场景&#xff1f; 一般用于动态加载配置项。比如lol&#xff0c;每天不断有人再投诉举报&#xff0c;客服根本忙不过来&#xff0c;腾讯内部做了一个判断&#xff0c;只有vip3…

Hadoop的第二个核心组件:MapReduce框架第四节

Hadoop的第二个核心组件&#xff1a;MapReduce框架 十、MapReduce的特殊应用场景1、使用MapReduce进行join操作2、使用MapReduce的计数器3、MapReduce做数据清洗 十一、MapReduce的工作流程&#xff1a;详细的工作流程第一步&#xff1a;提交MR作业资源第二步&#xff1a;运行M…

升哲科技城市级“算力+数字底座”服务亮相2023服贸会

9月2日至6日&#xff0c;以“开放引领发展&#xff0c;合作共赢未来”为主题的2023年中国国际服务贸易交易会在北京隆重举办。作为城市级数据服务商&#xff0c;升哲科技&#xff08;SENSORO&#xff09;连续第四年参加服贸会&#xff0c;携城市级“算力数字底座”服务及在城市…

【Apollo】自动驾驶技术的介绍

阿波罗是百度发布的名为“Apollo&#xff08;阿波罗&#xff09;”的向汽车行业及自动驾驶领域的合作伙伴提供的软件平台。 帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 百度开放此项计划旨在建立一个以合作为中…

halcon双目标定双相机标定

halcon双目标定 *取消更新 dev_update_off () *获取窗体句柄 dev_get_window (WindowHandle) *设置窗体字体样式 set_display_font (WindowHandle, 16, mono, true, false) *设置线条粗细 dev_set_line_width (3) *创建空对象 gen_empty_obj (ImageL) *读取指定文件内子集 li…

实现CenterNet图像分割算法模型的转换和量化(SDK0301-转ONNX编译)

一、实现CenterNet图像分割算法模型的转换和量化&#xff08;SDK0301-转ONNX编译&#xff09; 1、模型转换 &#xff08;1&#xff09;下载CenterNet算法移植代码&#xff1a; $ git clone https://github.com/sophon-ai-algo/examples.git # CenterNet示例项目代码位置 /ex…

Yolov5的tensorRT加速(python)

地址&#xff1a;https://github.com/wang-xinyu/tensorrtx/tree/master/yolov5 下载yolov5代码 方法一&#xff1a;使用torch2trt 安装torch2trt与tensorRT 参考博客&#xff1a;https://blog.csdn.net/dou3516/article/details/124538557 先从github拉取torch2trt源码 ht…

Power BI的发布到web按钮怎么没有?有人知道怎么办吗??????

Power BI的发布到web按钮怎么没有&#xff1f;有人知道怎么办吗&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; .

docker启动paddlespeech服务,并使用接口调用

一、检查docker容器是否启动 1.输入命令 systemctl status docker 启动 systemctl start docker 守护进程重启 sudo systemctl daemon-reload 重启docker服务 systemctl restart docker 重启docker服务 sudo service docker restart 关闭docker service docker…

使用 Python 的高效相机流

一、说明 让我们谈谈在Python中使用网络摄像头。我有一个简单的任务&#xff0c;从相机读取帧&#xff0c;并在每一帧上运行神经网络。对于一个特定的网络摄像头&#xff0c;我在设置目标 fps 时遇到了问题&#xff08;正如我现在所理解的——因为相机可以用 mjpeg 格式运行 30…

指针进阶(1)

指针进阶 朋友们&#xff0c;好久不见&#xff0c;这次追秋给大家带来的是内容丰富精彩的指针知识的拓展内容&#xff0c;喜欢的朋友们三连走一波&#xff01;&#xff01;&#xff01; 字符指针 在指针的类型中我们知道有一种指针类型为字符指针 char* &#xff1b; 使用方法如…