【算法】网络图中的dfs



快乐的流畅:个人主页


个人专栏:《算法神殿》《数据结构世界》《进击的C++》

远方有一堆篝火,在为久候之人燃烧!

文章目录

  • 引言
  • 一、单词搜索
  • 二、黄金矿工
  • 三、不同路径 |||
  • 四、图像渲染
  • 五、岛屿数量
  • 六、岛屿的最大面积
  • 七、被围绕的区域
  • 八、太平洋大西洋水流问题
  • 九、扫雷游戏
  • 总结

引言

在二维网络图中的dfs,反而一般不需要画决策树,因为在二维图像中有时候很直观可以看出决策关系,一般为上下左右搜索。

一、单词搜索


细节:

  • dfs函数设置返回值bool,以便及时调整路线
  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
  • pos设置为函数参数,方便回溯
class Solution
{int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};bool vis[7][7];int m, n;
public:bool dfs(vector<vector<char>>& board, int i, int j, string& word, int pos){if(pos == word.size()) return true;vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n && !vis[x][y] && board[x][y] == word[pos]){if(dfs(board, x, y, word, pos + 1)) return true;}}vis[i][j] = false;return false;}bool exist(vector<vector<char>>& board, string& word){m = board.size(), n = board[0].size();for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(board[i][j] == word[0]){if(dfs(board, i, j, word, 1)) return true;}}}return false;}
};

二、黄金矿工


细节:

  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
  • sum设置为函数参数,方便回溯
class Solution
{int ret = 0;bool vis[16][16];int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void dfs(vector<vector<int>>& grid, int i, int j, int sum){vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && grid[x][y]){dfs(grid, x, y, sum + grid[x][y]);}else ret = max(ret, sum);}vis[i][j] = false;}int getMaximumGold(vector<vector<int>>& grid){m = grid.size(), n = grid[0].size();for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(grid[i][j]){dfs(grid, i, j, grid[i][j]);}}}return ret;}
};

三、不同路径 |||


细节:

  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
  • path设置为函数参数,方便回溯
class Solution
{int ret = 0;int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};bool vis[20][20];int m, n, count = 0;
public:void dfs(vector<vector<int>>& grid, int i, int j, int path){if(grid[i][j] == 2){if(path + count == m * n) ++ret;return;}vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && grid[x][y] != -1){dfs(grid, x, y, path + 1);}}vis[i][j] = false;}int uniquePathsIII(vector<vector<int>>& grid){m = grid.size(), n = grid[0].size();int si, sj;for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(grid[i][j] == -1) ++count;else if(grid[i][j] == 1) {si = i, sj = j;}}}dfs(grid, si, sj, 1);return ret;}
};

  • 本题开始往后,是floodfill算法的练习
  • floodfill算法,本质就是寻找连通块
  • 同时floodfill算法没有回溯

四、图像渲染



细节:

  • 设置向量数组dx,dy
  • 记录baseColor, newColor
class Solution
{int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int baseColor, newColor;int m, n;
public:void dfs(vector<vector<int>>& image, int i, int j){image[i][j] = newColor;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n && image[x][y] == baseColor){dfs(image, x, y);}}}vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color){if(image[sr][sc] == color) return image;baseColor = image[sr][sc], newColor = color;m = image.size(), n = image[0].size();dfs(image, sr, sc);return image;}
};

五、岛屿数量


细节:

  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
class Solution
{int ret;bool vis[301][301];int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void dfs(vector<vector<char>>& grid, int i, int j){vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && grid[x][y] == '1'){dfs(grid, x, y);}}}int numIslands(vector<vector<char>>& grid){m = grid.size(), n = grid[0].size();for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(!vis[i][j] && grid[i][j] == '1'){dfs(grid, i, j);++ret;}}}return ret;}
};

六、岛屿的最大面积



细节:

  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
class Solution
{int ret, sum;vector<vector<bool>> vis;int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void dfs(vector<vector<int>>& grid, int i, int j){++sum;vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && grid[x][y] == 1){dfs(grid, x, y);}else ret = max(ret, sum);}}int maxAreaOfIsland(vector<vector<int>>& grid){m = grid.size(), n = grid[0].size();vis.resize(m, vector<bool>(n));for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(!vis[i][j] && grid[i][j] == 1){sum = 0;dfs(grid, i, j);}}}return ret;}
};

七、被围绕的区域


细节:

  • 正难则反,将边界上及其相连的‘O’先全部标记起来,最后遍历矩阵,将未被标记的‘O’改成‘X’
  • 设置向量数组dx,dy
  • 设置bool数组vis,实现剪枝
class Solution
{vector<vector<bool>> vis;int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void dfs(vector<vector<char>>& board, int i, int j){vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && board[x][y] == 'O'){dfs(board, x, y);}}}void solve(vector<vector<char>>& board){m = board.size(), n = board[0].size();vis.resize(m, vector<bool>(n));for(int i=0; i<m; ++i){if(board[i][0] == 'O') dfs(board, i, 0);if(board[i][n-1] == 'O') dfs(board, i, n-1);}for(int j=0; j<n; ++j){if(board[0][j] == 'O') dfs(board, 0, j);if(board[m-1][j] == 'O') dfs(board, m-1, j);}for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(!vis[i][j] && board[i][j] == 'O'){board[i][j] = 'X';}}}}
};

八、太平洋大西洋水流问题




思路:正难则反,水往高处流。

  • 利用两个标记数组,分别记录太平洋和大西洋的水可以流到的区域,找出标记数组重叠的部分即可。
  • 为了只用写一份dfs函数,将vis标记数组以参数的形式传递
  • 设置向量数组dx,dy
class Solution
{int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void dfs(vector<vector<int>>& heights, int i, int j, vector<vector<bool>>& vis){vis[i][j] = true;for(int k=0; k<4; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n&& !vis[x][y] && heights[x][y] >= heights[i][j])//正难则反,水往高处流{dfs(heights, x, y, vis);}}}vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights){m = heights.size(), n = heights[0].size();vector<vector<bool>> vis1(m, vector<bool>(n));vector<vector<bool>> vis2(m, vector<bool>(n));for(int i=0; i<m; ++i){if(!vis1[i][0]) dfs(heights, i, 0, vis1);if(!vis2[i][n-1]) dfs(heights, i, n-1, vis2);}for(int j=0; j<n; ++j){if(!vis1[0][j]) dfs(heights, 0, j, vis1);if(!vis2[m-1][j]) dfs(heights, m-1, j, vis2);}vector<vector<int>> ret;for(int i=0; i<m; ++i){for(int j=0; j<n; ++j){if(vis1[i][j] && vis2[i][j]){ret.push_back({i, j});}}}return ret;}
};

九、扫雷游戏



细节:本题实际上是一道模拟题,关键是理解题意。

  • 点击位置是雷,直接改变返回
  • 不是雷,则进入dfs函数递归
  • 对于当前格子,先计算周围8个格子中雷的数量
    • 如果有雷,将当前格子改为雷的数量,返回
    • 如果无雷,将当前格子改为挖出的空方块,继续递归
  • 递归的时候,要进行8个方向的搜索,所以向量数组要存储8个方向
class Solution
{bool vis[51][51];int dx[8] = {1, 1, 1, 0, 0, -1, -1, -1};int dy[8] = {1, 0, -1, 1, -1, 1, 0, -1};int m, n;
public:void dfs(vector<vector<char>>& board, int i, int j){if(board[i][j] == 'M') return;int count = 0;for(int k=0; k<8; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n && board[x][y] == 'M'){++count;}}if(count){board[i][j] = count + '0';return;}else board[i][j] = 'B';vis[i][j] = true;for(int k=0; k<8; ++k){int x = i + dx[k], y = j + dy[k];if(x >= 0 && y >= 0 && x < m && y < n && !vis[x][y]){dfs(board, x, y);}}}vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click){int ci = click[0], cj = click[1];if(board[ci][cj] == 'M'){board[ci][cj] = 'X';return board;}m = board.size(), n = board[0].size();dfs(board, ci, cj);return board;}
};

总结

网络图中的dfs,常用的搜索技巧,是创建向量数组dx,dy,方便简洁地用循环遍历。


真诚点赞,手有余香

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

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

相关文章

三磷酸腺苷(ATP)制备方法众多 主要应用于生化研究以及医药领域

三磷酸腺苷&#xff08;ATP&#xff09;制备方法众多 主要应用于生化研究以及医药领域 三磷酸腺苷&#xff08;ATP&#xff09;又称腺嘌呤核苷三磷酸、腺苷三磷酸&#xff0c;化学式为C10H16N5O13P3&#xff0c;是一种高能磷酸化合物。腺苷三磷酸外观呈白色粉末&#xff0c;无特…

2025秋招Java还是c++?

一、我的编程经 说说我的编程经历&#xff0c;在C和Java之间我经历了几个阶段&#xff1a; 大学期间&#xff0c;我浅尝辄止地学习了一段时间的Java&#xff0c;但后来放弃了&#xff0c;开始学习C/C。本科毕业后&#xff0c;我选择攻读硕士学位&#xff0c;并一直专注于C的学…

集成了Gemini的Android Studio,如虎添翼

今天将Android Studio升级到最新版&#xff08;Jellyfish&#xff09;。发现在new features中有一条&#xff1a; Code suggestions with Gemini in Android Studio 打开路径为&#xff1a; View > Tool Windows > Gemini 支持多国语言&#xff0c;英文、中文都能正确理解…

PPT为何无法复制粘贴?附解决办法!

PPT文件里的内容无法复制&#xff0c;或者复制后无法粘贴&#xff0c;这是怎么回事呢&#xff1f; 这种情况&#xff0c;一般是因为PPT被设置了保护&#xff0c;设置了以“只读方式”打开&#xff0c;就无法进行复制粘贴了。PPT的“只读方式”不同&#xff0c;解决方法也不同&…

Java入门基础学习笔记25——死循环和循环嵌套

死循环&#xff1a; 可以一直执行下去的一种循环&#xff0c;如果没有干预不会停下来。 死循环的写法&#xff1a; 例&#xff1a; package cn.ensource.loop;public class EndLessLoopDemo5 {public static void main(String[] args) {// 目标&#xff1b;掌握死循环的写法w…

力扣127.单词接龙讲解

距离上一次刷题已经过去了.........嗯............我数一一下............整整十天&#xff0c;今天再来解一道算法题 由于这段时间准备简历&#xff0c;没咋写博客。。今天回来了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

【React】如何让函数式组件也能使用state——useState(Hooks)

React的函数式组件不同于类式组件&#xff0c;函数式组件没有自己的 this&#xff0c;看似没有操作state的能力 但是React官方提供了一个Hooks叫useState&#xff0c;它解决了函数式组件和类式组件的差异&#xff0c;让函数式组件拥有了类式组件所拥有的 state &#xff0c;同时…

在win10折腾Flowise:部署和尝试

Flowise 是一种低代码/无代码拖放工具&#xff0c;旨在让人们轻松可视化和构建 LLM 应用程序。 本地部署 操作系统&#xff1a; win10 由于网络、操作系统等各种未知问题&#xff0c;使用npm install -g flowise的方式&#xff0c;尝试了很多次&#xff0c;都没有部署成功&am…

Visual C++界面开发组件Xtreme Toolkit Pro v24测试版发布——完全支持SVG

Codejock软件公司的Xtreme Toolkit Pro是屡获殊荣的VC界面库&#xff0c;是MFC开发中最全面界面控件套包&#xff0c;它提供了Windows开发所需要的11种主流的Visual C MFC控件&#xff0c;包括Command Bars、Controls、Chart Pro、Calendar、Docking Pane、Property Grid、Repo…

位图和布隆过滤器:位图

在《unordered_map 和 unordered_set》 中提到过&#xff1a; 哈希是一种思想&#xff0c;通过哈希函数将数据转化为一个或多个整型 —— 映射关系&#xff1b;通过这种映射关系&#xff0c;可以做到以 O(1) 的时间复杂度查找数据。 本文即将介绍的 位图 和 布隆过滤器 就是两个…

专“蜀”盛会!CGT Asia 2024 第六届亚洲细胞与基因治疗创新峰会(成都站)7月火热相邀

在细胞与基因治疗领域&#xff0c;我们正站在一个科技革命的风口上。中国的CGT市场预计将持续快速增长。根据相关分析&#xff0c;预计到2025年整体市场规模将达到25.9亿美元&#xff0c;显示出276%的复合年增长率。这一增长趋势预计将持续到2030年&#xff0c;细胞与基因治疗领…

【前端】TypeScript--未整理

概念 安装 npm install -g typescript 检查版本 tsc -v tsc 类型

redis-stack部署概要

第一步&#xff0c;下载redis-stack 下载链接&#xff1a;Downloads - Redis 第二步&#xff0c;redis安装包解压缩 gzip -d redis-stack-server-7.2.0-v10.rhel8.x86_64.tar.gz tar -xvf redis-stack-server-7.2.0-v10.rhel8.x86_64.tar 第三步&#xff0c;编辑etc下的redis…

IC设计企业如何实现安全便捷的芯片云桌面跨网摆渡?

IC设计企业&#xff0c;主要专注于集成电路的设计。这些企业通常包括集成电路、二极管、三极管和特殊电子元件等产品的设计和生产。IC设计企业在其运营和产品设计过程中&#xff0c;会涉及和产生多种文件&#xff0c;如&#xff1a; 项目需求文档&#xff1a;这是项目启动的基础…

停车场车位引导管理系统工作原理是什么,由哪些软硬件设备组成?

在现代城市中&#xff0c;随着汽车保有量的持续增长&#xff0c;停车难成为了许多城市面临的共同问题。有效管理停车场资源&#xff0c;提高车位利用率&#xff0c;减少寻找停车位的时间&#xff0c;对于缓解交通拥堵、提高城市运行效率具有重要意义。车位引导管理系统正是为了…

谷歌举办Gemini API开发者大赛;ChatGPT iOS版更新支持中文

&#x1f989; AI新闻 &#x1f680; 谷歌举办Gemini API开发者大赛&#xff0c;大奖1981款电动DeLorean 摘要&#xff1a;IT之家 5 月 15 日消息&#xff0c;在 2024 年谷歌 I/O 开发者大会上&#xff0c;谷歌宣布举办 Gemini API 开发者大赛&#xff0c;主要面向个人开发者…

24长三角数学建模ABC题已出!!!

需要ABC题资料的宝子们可以进企鹅 赛题如下&#xff1a; 赛道 A&#xff1a;“抢救”落水手机 上有天堂&#xff0c;下在苏杭&#xff1b;五一假期&#xff0c;杭州西湖、西溪湿地、京杭大运河等著名 景点&#xff0c;游人如织&#xff0c;作为享誉国内外的旅游胜地&#xff0…

图形程序复用新纪元 探讨云库安全分享计划

在公司的开放式办公室中&#xff0c;卧龙与凤雏相邻而坐。周围的同事们都在忙碌地工作&#xff0c;键盘敲击声不绝于耳。卧龙眉头紧锁&#xff0c;全神贯注地调试着复杂的代码&#xff0c;仿佛在挑战编程世界的极限。而凤雏则在完成了一段代码编写后&#xff0c;轻松地伸展着身…

联丰策略股票官网分析A股三大指数集体收跌,超3800只股票下跌

查查配今日A股三大指数集体收跌。沪指低开低走,午后A股上了微博热搜。 联丰策略拥有一支由知名互联网公司和国内证券金融机构的行业专家组成的一流运营团队。凭借他们在互联网产品开发和金融风险管理方面的丰富经验,我们的团队致力于为客户提供专业和个性化的证券交易服务。 截…

Java环境搭配(一)JDK下载以及介绍、path环境变量配置

目录 JDK Development Kit &#xff08;JDK&#xff09; 下载 JDK介绍 &#xff1a; JDK 包括以下主要组件 配置path环境变量 在cmd上打印Helloworld JDK Development Kit &#xff08;JDK&#xff09; 下载 下载官方地址 www.oracle.com 进入网址后&#xff1a; 点击产…