对于矩阵,直观上可以想象的遍历方式按行、列,有些题目还有螺旋遍历,实际题目很多是需要BFS或者DFS的。技巧是结果空间遍历其实是4个方向的选择。
这里简单记录一个比较典型的题目–矩阵中最长递增序列[leetcode-329]。原问题还有一点是考察任意点开始的最长路径,这里简化了下,毕竟只想研究BFS和DFS。
其实在图的遍历过程中,辅助isVisited数组是很常用的,这里BFS没有使用isVisited数组是因为最大增序保证了不会往回走。而DFS的辅助数组是不是就是isVisited数组呢,起码起到了部分作用,作为递归的结束条件。
import java.util.*;
public class matrixTraveral {
static int[][] dirs = new int[][]{{-1,0},{0, -1},{1,0},{0,1}};
static int[][] longestPath = new int[3][3];
public static void main(String[] args) {
int[][] matrix = new int[][]{
{9,9,4},
{6,6,8},
{2,1,1}
};
System.out.println(DFS(matrix, 2,1));
}
static int BFS(int[][] matrix, int x, int y){
int n = matrix.length;
int m = matrix[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{x,y});
int ans = 0;
while(!queue.isEmpty()){
ans++;
int size = queue.size();
for(int s=0;s<size;s++){
int[] poll = queue.poll();
int i = poll[0];
int j = poll[1];
for(int[] dir:dirs){
int nextI = i+dir[0];
int nextJ = j+dir[1];
if(nextI>=0&&nextJ>=0&&nextJ<m&&nextI<n&&matrix[nextI][nextJ]>matrix[i][j]){
queue.offer(new int[]{nextI, nextJ});
}
}
}
}
return ans;
}
static int DFS(int[][] matrix, int x, int y){
if(longestPath[x][y] != 0) return longestPath[x][y];
int n = matrix.length;
int m = matrix[0].length;
longestPath[x][y] = 1;
for(int[] dir:dirs){
int nextI = x+dir[0];
int nextJ = y+dir[1];
if(nextI>=0&&nextJ>=0&&nextJ<m&&nextI<n&&matrix[nextI][nextJ]>matrix[x][y]){
longestPath[x][y] = Math.max(longestPath[x][y], DFS(matrix, nextI, nextJ)+1);
}
}
return longestPath[x][y];
}
}