package com.lyk.kk; /** * Created by Administrator on 2017/9/7. * 矩阵的最小路径和 * 给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达左下角的位置,路径上所有数组的累加起来就是路径和,返回所有路径中最小的路径和 * 如果给定的m如下 * 1 3 5 9 * 8 1 3 4 * 5 0 6 1 * 8 8 4 0 * 解答。经典动态规划方法。假设矩阵m的太小为M*N,行数为M,列数为N,先生成太小和m一样的矩阵dp. * dp[i][j]的值表示从左上角(即(0,0))位置走到(i,j)位置的最小路径和。 */ public class A4 { //第一种方法 时间复杂度O(M*N) 额外空间复杂度为(M*N) public int minPathSum1(int [][]m){ if(m==null||m.length==0||m[0]==null||m[0].length==0){ return 0; } int [][]dp=new int[m.length][m[0].length]; dp[0][0]=m[0][0]; for(int i=1;i<m.length;i++){ dp[i][0]=dp[i-1][0]+m[i][0]; } for(int j=1;j<m[0].length;j++){ dp[0][j]=dp[0][j-1]+m[0][j]; } for(int i=1;i<m.length;i++){ for(int j=1;j<m[0].length;j++){ dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+m[i][j]; } } return dp[m.length-1][m[0].length-1]; } //第二种方法 /** * 1.动态规划经过空间压缩后的方法。使用太小为min{M,N}的arr数组。额外时间复杂度为O(min{M,N}) *生成长度为4的数组arr,初始时arr=[0000].我们知道从(0,0)位置到达m中第一行的每个位置,最小的了路径和就是从(0,0)位置的值开始依次累加的结果,所以依次 * 把arr设置为arr=[1 4 9 18],此时arr[j]的值代表从(0,0)位置到达(0,j)位置的最小路径和。 * 2.步骤1中arr[j]的值代表从(0,0)位置到达(0,j)位置的最小路径和,在这一步中 * 想把arr[j]的值更新成从(0,0)到(1,j)的最小路径和。 * 首先来看arr[0],更新之前arr[0]代表从(0,0)位置到达(0,0)位置的最小路径和(dp[0][0]). * 如果想把arr[0]更新成从(0,0)位置到达(1,0)位置的最小路径和(dp[1][0])arr[0]=arr[0]+m[1][0];=9 * 然后在来看arr[1],更新之前arr[1]的值代表从(0,0)位置到达(0,1)位置的最小路径和(dp[0][1]), * 更新之后想让arr[1]代表从(0,0)位置到达(1,1)位置的最小路径和dp[1][1]. * 根据动态规划的求解过程,到达(1,1)位置有两种选择。一种是从(1,0)位置到达(1,1)位置(dp[1][0]+m[1][1]), * 另外一种从(0,1)位置到达(1,1)位置(dp[0][1]+m[1][1]),应该选择路径最小的那个。 * 3.重复步骤2的更新过程,一直到arr彻底变成dp矩阵的最后一行。整个过程其实就是不断滚动更新arr数组,
让arr一次变成dp矩阵每一行的值。最终变成dp矩阵最后一行的值。 */ public int minPathSum2(int [][]m){ if(m==null||m.length==0||m[0]==null||m[0].length==0){ return 0; } int more=Math.max(m.length,m[0].length);//行,列 中大的那一方 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]=arr[0]+(rowmore?m[i][0]:m[0][i]); for(int j=1;j<less;j++){ arr[j]=Math.max(arr[j]-1,arr[j])+(rowmore?m[i][j]:m[j][i]); } } return arr[less-1]; } }