码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵的最小路径和

时间:2018-08-02 02:13:41      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:max   辅助   break   最小值   开始   矩阵   get   java   ack   

* 问题

  给定一个矩阵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

  

矩阵的最小路径和

标签:max   辅助   break   最小值   开始   矩阵   get   java   ack   

原文地址:https://www.cnblogs.com/mingzhanghui/p/9404642.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!