[算法]深度优先搜索DSF
DFS(深度优先搜索 Depth-First-Search)[1]
DFS基本介绍
是一种用于遍历或搜索树或图的算法。这个算法会尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。这种算法不会根据图的结构等信息调整执行策略。
深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的拓扑排序表1,利用拓扑排序表可以方便的解决很多相关的图论问题,如无权最长路径问题等等。
因发明“深度优先搜索算法”,约翰·霍普克洛夫特与罗伯特·塔扬在1986年共同获得计算机领域的最高奖:图灵奖。
DFS实现方法
- 首先将根节点放入stack中。
- 从stack中取出第一个节点,并检验它是否为目标。
如果找到目标,则结束搜寻并回传结果。
否则将它某一个尚未检验过的直接子节点加入stack中。 - 重复步骤2。
- 如果不存在未检测过的直接子节点。
将上一级节点加入stack中。
重复步骤2。 - 重复步骤4。
- 若stack为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。
算法题
矩阵最长递增路径[2]
给定一个矩阵,矩阵内所有数均为非负整数。
求一条路径,该路径上所有数是递增的。
这个路径必须满足以下条件:
1、对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
2、你不能走重复的单元格。即每个格子最多只能走一次。
输入: [[1,2,3],[4,5,6],[7,8,9]] 输出:5 原因:1->2->3->6->9即可(当然这种递增路径不是唯一的)
解法如下:
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 递增路径的最大长度
* @param matrix int整型二维数组 描述矩阵的每个数
* @return int整型
*/
public int solve (int[][] matrix) {
int maxLength = 0;
//存储已经遍历过的路径长度,这个是点睛之笔,避免了了重复计算
int[][] checked = new int[matrix.length][matrix[0].length];
//每个节点有四个方向可以行进
int[][] paths = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
//遍历每个节点,获取最大长度
for (int row = 0;row < matrix.length;row++) {
for (int col = 0;col < matrix[0].length;col++) {
int length = getMaxLength(matrix, row, col, checked, paths);
if (maxLength < length) {
maxLength = length;
}
}
}
return maxLength;
}
//递归查找节点的四个方向找出符合方向的节点并返回长度+1
private int getMaxLength(int[][] m, int row, int col, int[][] checked, int[][] paths) {
int length = 0;
int maxLength = 0;
//已经计算过就不再重复计算
if(checked[row][col] > 0) {
return checked[row][col];
}
//递归查找节点的四个方向找出符合方向的节点并返回长度 +1
for (int[] path : paths) {
int movedRow = row + path[0];
int movedCol = col + path[1];
if (0 <= movedRow && movedRow < m.length &&
0 <= movedCol && movedCol < m[0].length &&
m[row][col] < m[movedRow][movedCol]) {
length = getMaxLength(m, movedRow, movedCol, checked, paths);
}
if (length > maxLength){
maxLength = length;
}
}
//记录已经计算过的节点,其作为起点的最长长度
checked[row][col] = maxLength + 1;
return checked[row][col];
}
}
本质上就是上述提到的DFS算法。对于数组的查询,以一个元素作为根节点root,接下来的过程就是利用DFS,以root节点开始对四个节点进行搜索。
参考
1.深度优先搜索, https://zh.wikipedia.org/wiki/%E6%B7%B1%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2
2. 矩阵最长递增路径,https://www.nowcoder.com/practice/7a71a88cdf294ce6bdf54c899be967a2?tpId=196&tqId=37184&rp=1&ru=%2Fta%2Fjob-code-total&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey