* 问题
给定一个矩阵m,从左上角开始每次只能向右或者乡下走,最后叨叨右下角的位置,路径上所有的数字累加起来就是路径和,返回所有的路径中最小的路径和。
1 -> 3 5 9
8 1 3 4
5 0 -> 6 -> 1
8 8 4 0
打印最小路径:
1->3->1->0->6->1->0
package cn.mediamix;
import java.util.ArrayList;
import java.util.LinkedList;
public class MinPath {
public static int[][] minPath(int[][] m) {
if (m==null||m.length==0||m[0]==null||m[0].length==0) {
return null;
}
int row = m.length, col = m[0].length;
int [][]dp = new int[row][col];
dp[0][0] = m[0][0];
for (int i = 1; i < row; i++) {
dp[i][0] = dp[i-1][0] + m[i][0];
}
for (int j = 1; j < col; j++) {
dp[0][j] = dp[0][j-1] + m[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + m[i][j];
}
}
// return dp[row-1][col-1];
return dp;
}
public static String getPath(int [][]dp) {
ArrayList<Integer> a = new ArrayList<Integer>(dp.length + dp[0].length - 1);
int i = dp.length-1, j = dp[0].length-1;
while (0<=i && 0 <= j) {
a.add(dp[i][j]);
if (0<i && 0<j) {
if (dp[i-1][j] < dp[i][j-1]) {i--;}
else {j--;}
} else if (0 < i) {
i--;
} else if (0 < j) {
j--;
} else {
break;
}
}
LinkedList<Integer> list = new LinkedList<Integer>();
for (i = 0; i < a.size()-1; i++) {
list.push(a.get(i)-a.get(i+1));
}
list.push(a.get(i));
StringBuilder sb = new StringBuilder();
for(Integer elem:list) {
sb.append(elem + "->");
}
sb.delete(sb.length()-2, sb.length());
return sb.toString();
}
// 空间压缩 不可打印路径
public static int minPathSum2(int[][] m) {
if (m==null||m.length==0||m[0]==null||m[0].length==0) {
return 0;
}
// 行数与列数较大的那个为more
int more = Math.max(m.length, m[0].length);
// 行数与列数较小的那个为less
int less = Math.min(m.length, m[0].length);
// 行数是不是>=列数
boolean rowMore = more == m.length;
// 辅助数组的长度仅为行数与列数的最小值
int [] arr = new int [less];
arr[0] = m[0][0];
for (int i = 1; i < less; i++) {
arr[i] = arr[i-1] + (rowMore ? m[0][i] : m[i][0]);
}
for (int i = 1; i < more; i++) {
arr[0] += (rowMore ? m[i][0]:m[0][i]);
for (int j = 1; j < less; j++) {
arr[j] = Math.min(arr[j-1], arr[j]) +
(rowMore ? m[i][j] : m[j][i]);
}
}
return arr[less-1];
}
public static void main(String[] args) {
int [][]m = {
{1,3,5,9},
{8,1,3,4},
{5,0,6,1},
{8,8,4,0}
};
int [][]dp = minPath(m);
System.out.println(dp[dp.length-1][dp[0].length-1]);
System.out.println(getPath(dp));
System.out.println(minPathSum2(m));
}
}
Output:
12
1->3->1->0->6->1->0
12
原文:https://www.cnblogs.com/mingzhanghui/p/9404642.html