public class Main { public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}}; public static int dfs(int x,int y,int[][] a,int[][] visited,int upOrDown,int m,int n){ visited[x][y]=1; int res=0; for(int i=0;i<4;++i){ int nx = x+dir[i][0]; int ny = y+dir[i][1]; if(nx<0||nx>=m||ny<0||ny>=n){ continue; } if(visited[nx][ny]==1){ continue; } if(a[nx][ny]==a[x][y]){ continue; } if(upOrDown==1&&a[nx][ny]>a[x][y]){ continue; } if(upOrDown==0&&a[nx][ny]<a[x][y]){ continue; } res=Math.max(res,1+dfs(nx, ny, a, visited, 1-upOrDown, m, n)); } visited[x][y]=0; return res; } public static int solution(int m, int n, int[][] a) { int res=0; int[][] visited = new int[m][n]; for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ int steps1 = dfs(i,j,a,visited,0,m,n); int steps2 = dfs(i,j,a,visited,1,m,n); int steps=Math.max(steps1,steps2); res=Math.max(steps,res); } } return res; } } 算法思路 这个算法是用来解决一个特定类型的图遍历问题,其中图是由一个二维数组 a 表示的,每个元素的值代表该位置的高度。目标是找到从任意起点出发,能够经过的最大不同高度的位置数量(即最长路径),且路径必须满足以下规则: 移动方向:只能向上下左右四个方向移动。 高度限制: 如果从较低的高度移动到较高的高度(上坡),则下一步可以继续上坡或保持在同一高度或下坡。 如果从较高的高度移动到较低的高度(下坡),则下一步只能继续下坡或保持在同一高度。 算法使用深度优先搜索(DFS)来遍历所有可能的路径,并跟踪每个位置的最大可移动次数。 解题思路 初始化: 定义一个方向数组 dir,包含四个方向的移动(右、下、左、上)。 定义一个二维数组 visited 来记录每个位置是否已经被访问过,以避免重复访问。 深度优先搜索(DFS) 定义一个递归函数 dfs,它接受当前位置 (x, y)、二维数组 a、访问数组 visited、当前是上坡还是下坡的标志 upOrDown(1代表上坡,0代表下坡)、以及数组的行数 m 和列数 n。 在 dfs 函数中,首先标记当前位置为已访问。 遍历四个方向,对于每个方向上的新位置 (nx, ny): 检查边界条件和是否已访问。 检查高度条件:如果上坡而来,则新位置高度不能低于当前位置;如果下坡而来,则新位置高度不能高于当前位置。 如果满足条件,则递归调用 dfs,并将结果加1(表示当前这一步),然后更新最大步数 res。 回溯时,将当前位置标记为未访问,以便其他路径可以使用。 遍历所有起点: 在 solution 函数中,遍历二维数组 a 的每个位置作为起点。 对于每个起点,分别计算从上坡和下坡开始的最大步数,并取两者中的较大值。 更新全局最大步数 res。 返回结果: 返回全局最大步数 res,即从任意起点出发能够经过的最大不同高度的位置数量。