LeetCode64题:最小路径和

版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/ASN_forever/article/details/85247664

思路:

 题目要求的是从左上角即[0,0]位置开始,到右下角即[m-1,n-1]位置为止的最小路径和。倒过来思考的话,对于右下角[m-1,n-1]来说,它的上一步只有两个位置即[m-2,n-1]和[m-1,n-2],因此问题就可以转化为求从[0,0]到这两个位置的路径和的较小值,即状态转移公式为:min ( arr[m-1][n-1] ) = min ( arr[m-1][n-1]+min( arr[m-2][n-1] ),arr[m-1][n-1]+min( arr[m-1][n-2] )),因此可以很容易的用递归方式求解。

解法一:递归法

public int minPathSum(int[][] grid) {
        return help1(grid,grid.length-1,grid[0].length-1);
    }
public int help1(int[][] arr,int row,int col){
        if(row == 0 && col == 0){
            return arr[row][col];
        }
        if(row != 0 && col == 0){
            return arr[row][col]+help1(arr,row-1,col);
        }
        if(row == 0 && col != 0){
            return arr[row][col]+help1(arr,row,col-1);
        }
        return arr[row][col]+Math.min(help1(arr,row-1,col),help1(arr,row,col-1));
    }

但是递归法涉及到很多的重复计算,时间复杂度超时,因此需要换一种思路。刚才采用递归法时,考虑的是从后往前求解,那么现在反过来,从前往后可不可以呢?如果能从前往后计算的话,那么就可以依次求出从左上角到任意一个位置的最小路径和了,因为要求的这个位置之前的两个位置的最小值已经知道了,这样就不存在重复计算(即动态规划法)。那么这种思路能不能实现呢?接着思考,对于二维数组来说,在边界上的位置,它的上一步只有一个,而处在中间位置的才有两个。而对二维数组进行遍历的时候,就是从上到下从左到右的遍历的,跟路径的行走规则一致,那么就可以在遍历的时候直接求出每个位置的最小路径和了。

解法二:动态规划法

public int minPathSum(int[][] grid) {
        return help(grid);
    }
    public int help(int[][] arr){
        int row = arr.length;
        int col = arr[0].length;
        for(int i=0;i<row;i++){
        	for(int j=0;j<col;j++){
        		if(i == 0 && j == 0){
        			continue;
        		}
        		if(i != 0 && j != 0){
        			arr[i][j] += Math.min(arr[i-1][j], arr[i][j-1]); 
        		}else if(i == 0){
        			arr[i][j] += arr[i][j-1]; 
        		}else{
        			arr[i][j] += arr[i-1][j];
        		}
        	}
        }
        return arr[row-1][col-1];
    }

猜你喜欢

转载自blog.csdn.net/ASN_forever/article/details/85247664