LeetCode Top 100 Liked Questions 64. Minimum Path Sum (Java版; Medium)
题目描述
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Example:
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.
第一次做, 进一步降低空间复杂度, 直接在原数组上进行修改, 不用额外申请空间了; 不论哪种动态规划的写法, 都有同一个特点: 每个点(i,j)都访问两次, 第一次访问是计算(0,0)到(i,j)的距离; 第二次访问是获取(0,0)到(i,j)的最短距离和
class Solution {
public int minPathSum ( int [ ] [ ] grid) {
if ( grid== null || grid. length== 0 || grid[ 0 ] . length== 0 )
return 0 ;
int rows = grid. length, cols = grid[ 0 ] . length;
for ( int j= 1 ; j< cols; j++ )
grid[ 0 ] [ j] = grid[ 0 ] [ j- 1 ] + grid[ 0 ] [ j] ;
for ( int i= 1 ; i< rows; i++ )
grid[ i] [ 0 ] = grid[ i- 1 ] [ 0 ] + grid[ i] [ 0 ] ;
for ( int i= 1 ; i< rows; i++ ) {
for ( int j= 1 ; j< cols; j++ ) {
grid[ i] [ j] = Math. min ( grid[ i] [ j- 1 ] , grid[ i- 1 ] [ j] ) + grid[ i] [ j] ;
}
}
return grid[ rows- 1 ] [ cols- 1 ] ;
}
}
第一次做, 降低空间复杂度, 空间复杂度 O(N); 利用了移动的规律, 只有向右或者向下移动, 所以只保存一行状态即可
class Solution {
public int minPathSum ( int [ ] [ ] grid) {
if ( grid== null || grid. length== 0 || grid[ 0 ] . length== 0 )
return 0 ;
int [ ] arr = new int [ grid[ 0 ] . length] ;
arr[ 0 ] = grid[ 0 ] [ 0 ] ;
for ( int j= 1 ; j< grid[ 0 ] . length; j++ )
arr[ j] = arr[ j- 1 ] + grid[ 0 ] [ j] ;
for ( int i= 1 ; i< grid. length; i++ ) {
for ( int j= 0 ; j< grid[ 0 ] . length; j++ ) {
if ( j== 0 ) {
arr[ j] = arr[ j] + grid[ i] [ j] ;
}
else {
arr[ j] = Math. min ( arr[ j- 1 ] , arr[ j] ) + grid[ i] [ j] ;
}
}
}
return arr[ grid[ 0 ] . length- 1 ] ;
}
}
第一次做, 用动态规划; 从左上角到右下角; 时间复杂度O(m*n), 空间复杂度O(m*n), 可以把空间复杂度降低
class Solution {
public int minPathSum ( int [ ] [ ] grid) {
if ( grid== null || grid. length== 0 || grid[ 0 ] . length== 0 )
return 0 ;
int [ ] [ ] dp = new int [ grid. length] [ grid[ 0 ] . length] ;
dp[ 0 ] [ 0 ] = grid[ 0 ] [ 0 ] ;
for ( int i= 1 ; i< grid. length; i++ )
dp[ i] [ 0 ] = dp[ i- 1 ] [ 0 ] + grid[ i] [ 0 ] ;
for ( int j= 1 ; j< grid[ 0 ] . length; j++ )
dp[ 0 ] [ j] = dp[ 0 ] [ j- 1 ] + grid[ 0 ] [ j] ;
for ( int i= 1 ; i< grid. length; i++ ) {
for ( int j= 1 ; j< grid[ 0 ] . length; j++ ) {
dp[ i] [ j] = Math. min ( dp[ i- 1 ] [ j] , dp[ i] [ j- 1 ] ) + grid[ i] [ j] ;
}
}
return dp[ grid. length- 1 ] [ grid[ 0 ] . length- 1 ] ;
}
}