问题描述:
给定一个n x m矩阵,其中单元格的取值为0,或者1。0表示单元格为空;1表示单元格不为空。您的站位,在单元格中用2表示。
您可以垂直向上或向下、水平向左或向右移动到任何空单元格。
您的任务是找到能够到达该二维矩阵任何边界(边缘)的最小步数(Step)。
如果无法到达任何边界(边缘),请输出 -1。
注意:整个矩阵中只有一个值为2的单元格。
例如:
给定一个二维矩阵
matrix[] = {1, 1, 1, 0, 1}
{1, 0, 2, 0, 1}
{0, 0, 1, 0, 1}
{1, 0, 1, 1, 0}
输出:2
解释:找到你的站位,然后向右移动,在向上移动,即可到达二维矩阵的边界。
给定一个二维矩阵
matrix[] = {1, 1, 1, 1, 1}
{1, 0, 2, 0, 1}
{1, 0, 1, 0, 1}
{1, 1, 1, 1, 1}
输出: -1
解释:找到你的站位,你无法移动到该二维矩阵的边界。
使用动态规划算法来解决该问题,思路如下:
package com.bean.algorithm.basic;
public class FindMinStepsReachEdge {
//r表示row,c表示col,即4行5列
static final int r=4,c=5;
static int findMinSteps(int mat[][], int n, int m, int dp[][], boolean vis[][])
{
// 到达边界,则返回
if (n == 0 || m == 0 || n == (r - 1) || m == (c - 1)) {
return 0;
}
if (dp[n][m] != -1)
return dp[n][m];
// 访问该位置
vis[n][m] = true;
int ans1, ans2, ans3, ans4;
ans1 = ans2 = ans3 = ans4 = (int)1e9;
// 向上
if (mat[n - 1][m] == 0) {
if (!vis[n - 1][m])
ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis);
}
// 向右
if (mat[n][m + 1] == 0) {
if (!vis[n][m + 1])
ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis);
}
// 向左
if (mat[n][m - 1] == 0) {
if (!vis[n][m - 1])
ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis);
}
// 向下
if (mat[n + 1][m] == 0) {
if (!vis[n + 1][m])
ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis);
}
// 最小路径
dp[n][m] = Math.min(ans1, Math.min(ans2, Math.min(ans3, ans4)));
return dp[n][m];
}
// 返回step的最小值
static int minimumSteps(int mat[][], int n, int m)
{
//用来表示你的站位
int twox = -1;
int twoy = -1;
// 在矩阵中找到 '2'
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mat[i][j] == 2) {
twox = i;
twoy = j;
break;
}
}
if (twox != -1)
break;
}
// 初始化二维dp数组
int dp[][]=new int[r][r];
for(int j=0;j= 1e9)
return -1;
else
return res;
}
public static void main(String args[])
{
int mat[][] = {
{ 1, 1, 1, 0, 1 },
{ 1, 0, 2, 0, 1 },
{ 0, 0, 1, 0, 1 },
{ 1, 0, 1, 1, 0 }
};
System.out.println( minimumSteps(mat, r, c));
}
}
程序运行结果:
2