这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战
BFS/DFS
广搜
- 以v为起始点,由近至远依次访问和v路径想通且路径长度为1,2,…的顶点,是一种分层的查找过程
- 为了实现逐层的访问,算法必须借助一个
辅助队列
(vis 数组和队列) - 算法过程可以看做是图上
火苗传播的过程
:最开始只有起点着火了,在每一时刻,有火的节点都向它相邻的所有节点传播火苗。 时间复杂度 O(n+m) 空间复杂度 O(n)
深搜
- 所谓’深度优先’,就是说每次都尝试向’更深的节点走’
- DFS 最显著的特征在于其 递归调用自身 。同时与 BFS 类似,DFS 会对其访问过的点打上
访问标记
, - 在遍历图时跳过已打过标记的点,以确保 每个点仅访问一次
时间复杂度
O(n+m)空间复杂度
O(n)其中n表示点数,m表示边数,复杂度包含了栈空间,栈空间的空间复杂度是 O(n)
重头戏两道题
1
- 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
输入: m = 2, n = 3, k = 1
输出: 3
- 首先我们明确,是否可以去使用
深搜
从左上角开始出发,只有两个方向那就是下和右 - 想出辅助函数是深搜,再去思考终止条件是什么,什么时候返回,来看下面的代码
class Solution {
boolean[][] v;
public int movingCount(int m, int n, int k) {
// 用来标记是否走过
v = new boolean[m][n];
return dfs(m,n,0,0,k);
}
int dfs(int m,int n,int x,int y,int k) {
// 特判不成立情况
if (x < 0 || x >= m || y < 0 || y >= n || v[x][y] ||
(x%10 + x/10 + y%10 + y/10) > k) return 0;
v[x][y] = true;
// 返回成功情况(右和下两个方向)
return 1 + dfs(m,n,x+1,y,k) + dfs(m,n,x,y+1,k);
}
}
2
- 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
- 例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
- 首先思考是否可以使用
深搜
,每个字母是否都有四个方向 - 回想第一题,去确定辅助函数的,终止条件是什么,什么时候返回,看代码!
class Solution {
public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();
// 遍历整个二维数组
for (int i = 0; i < board.length; i++) {
for (int j = 0 ; j < board[0].length; j++) {
if (dfs(board,words,i,j,0)) return true;
}
}
return false;
}
boolean dfs (char[][] board,char[] word,int i,int j,int k) {
if (i < 0 || i >= board.length || j < 0 || j>= board[0].length ||
board[i][j] != word[k]) return false;
if(word.length - 1 == k) return true;
// 特殊占位符
board[i][j] = '\0';
// 上下左右四个方向
boolean res =
dfs(board,word,i+1,j,k+1) ||
dfs(board,word,i-1,j,k+1) ||
dfs(board,word,i,j+1,k+1) ||
dfs(board,word,i,j-1,k+1);
// 还原回来数据
board[i][j] = word[k];
return res;
}
}
总结
- 诸如上面的两道题都是矩阵里面去搜索,其实我们都可以使用深搜
- 按照老规矩去写辅助函数,确定好出口在哪里,特判条件,到底该设置几个参数
- 最后就是完整地写出了DFS!🐯
今天的文章对「深搜/广搜」的感悟🤑分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19318.html