Leetcode's typical dynamic programming problem trilogy

This article summarizes the three classic dynamic programming problems of Leetcode : minimum path sum, different path 1, different path 2

1. Minimum path sum

Title description

Given an mxn grid containing non-negative integers, please find a path from the upper left corner to the lower right corner so that the sum of the numbers on the path is the smallest.

Note: You can only move one step down or right at a time.

Example:

Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: the smallest sum because the path 1 → 3 → 1 → 1 → 1 in.

Ideas

Typical dynamic programming, recursive formula:

dp[i][j] = grid[i][j]                                     (i=0,j=0)
dp[i][j] = dp[i-1][j]+grid[i][j]                          (i>0,j=0)
dp[i][j] = dp[i][j-1]+grid[i][j]                          (i=0,j>0)
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]       (i>0,j>0)

Java code

public class 最小路径和64 {
	public static int minPathSum(int[][] grid) {
	        if(grid == null) return 0;
	        
	        int m = grid.length;
	        int n = grid[0].length;
	        int[][] dp = new int[m][n];
	        
	        for(int i = 0;i<m;i++){
	            for(int j = 0;j<n;j++){
	                if(i == 0 && j == 0){
	                    dp[i][j] = grid[i][j];
	                }else if(i == 0 && j!=0){
	                    dp[i][j] = dp[i][j-1]+grid[i][j];
	                }else if(i!=0 && j==0){
	                    dp[i][j] = dp[i-1][j]+grid[i][j];
	                }
	                else{
	                    dp[i][j] = grid[i][j]+Math.min(dp[i-1][j],dp[i][j-1]);
	                }
	            }
	        }
	        return dp[m-1][n-1];
	    }
	    //测试 main方法入口
	    public static void main(String[] args) {
		int[][] grid = {
   
   {1,3,1},
		  {1,5,1},
		  {4,2,1}};
		int minPathSum2 = minPathSum2(grid);
		System.out.println(minPathSum2);
	}
}

2. A different path

Title description

A robot is located in the upper left corner of an mxn grid (the starting point is marked as "Start" in the figure below).

The robot can only move one step down or to the right at a time. The robot tries to reach the bottom right corner of the grid (labeled "Finish" in the image below).
image

How many different paths are there in total?

For example, the image above is a 7 x 3 grid. How many possible paths are there?

Note: The values ​​of m and n do not exceed 100.

Example 1:

Input: m = 3, n = 2
Output: 3
Explanation:
Starting from the upper left corner, there are a total of 3 paths to the lower right corner.

  1. Right -> Right -> Down
  2. Right -> Down -> Right
  3. Down -> Right -> Right
    Example 2:

Input: m = 7, n = 3
Output: 28

Ideas

A very classic dynamic programming

  • When the end point is at the border, there must be only one way, so
if(i == 0 || j == 0){
	dp[i][j] = 1;
}
  • When the end point is not on the boundary, the number of roads at the current end point is equal to the sum of the number of roads above it and the left node, namely:
dp[i][j] = dp[i-1][j]+dp[i][j-1];

Java code

public class 不同路径62 {

	public static int uniquePaths(int m, int n) {
	        int[][] dp = new int[m][n];
	        for(int i = 0;i<m;i++){
	            for(int j = 0;j<n;j++){
	                if(i == 0 || j == 0){
	                    dp[i][j] = 1;
	                }else{
	                    dp[i][j] = dp[i-1][j]+dp[i][j-1];
	                }
	            }
	        }
	        return dp[m-1][n-1];
	    }
	
	public static void main(String[] args) {
		int uniquePaths = uniquePaths(3,2);
		System.out.println(uniquePaths);
	}
}

3. Different paths two

Title description

A robot is located in the upper left corner of an mxn grid (the starting point is marked as "Start" in the figure below).

The robot can only move one step down or to the right at a time. The robot tries to reach the bottom right corner of the grid (labeled "Finish" in the image below).

image
Now consider that there are obstacles in the grid. So how many different paths will there be from the upper left corner to the lower right corner?
Obstacles and empty positions in the grid are represented by 1 and 0 respectively.

Note: The values ​​of m and n do not exceed 100.

Example 1:

Input:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
Output: 2
Explanation:
There is an obstacle in the middle of the 3x3 grid.
There are 2 different paths from the upper left corner to the lower right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

Ideas

It is still a typical dynamic programming, which adds obstacles compared to the previous question .

Separate the boundary and internal calculations so that it will be clearer.

  • Boundary, if there is an obstacle at a certain point on the boundary, the number of roads to that point is 0; if there is no obstacle, the number of roads to this point is equal to the number of roads to a point before it. Corresponding in the code:
//行(左边框)
for(int i = 1;i<rows;i++){
     if(obstacleGrid[i][0] == 1){
         dp[i][0] = 0;
     }else{
         dp[i][0] = dp[i-1][0];
     }
 }
        
//列(上边框)
for(int i = 1;i<columns;i++){
    if(obstacleGrid[0][i] == 1){
        dp[0][i] = 0;
    }else{
        dp[0][i] = dp[0][i-1];
    }
}
  • Inside, if there is an obstacle inside a certain point, the number of ways to reach that point is 0; if there is no obstacle, the number of ways to reach that point is equal to the sum of the number of ways to reach the node above it and the node on the left . Corresponding in the code:
//行列(内部)
for(int i=1;i<rows;i++){
      for(int j = 1;j<columns;j++){
          dp[i][j] = obstacleGrid[i][j] == 1?0:dp[i-1][j]+dp[i][j-1];
      }
  }

Java code

public class 不同路径二63 {
	
	public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if(obstacleGrid == null||obstacleGrid.length == 0) return 0;
        int rows = obstacleGrid.length;
        int columns = obstacleGrid[0].length;
       
        int[][] dp = new int[rows][columns];
        
        if(obstacleGrid[0][0] == 1){
            dp[0][0] = 0;
        }else{
            dp[0][0] = 1;
        }
        
        //行(左边框)
        for(int i = 1;i<rows;i++){
            if(obstacleGrid[i][0] == 1){
                dp[i][0] = 0;
            }else{
                dp[i][0] = dp[i-1][0];
            }
        }
        
         //列(上边框)
        for(int i = 1;i<columns;i++){
            if(obstacleGrid[0][i] == 1){
                dp[0][i] = 0;
            }else{
                dp[0][i] = dp[0][i-1];
            }
        }
        
        //行列(内部)
        for(int i=1;i<rows;i++){
            for(int j = 1;j<columns;j++){
                dp[i][j] = obstacleGrid[i][j] == 1?0:dp[i-1][j]+dp[i][j-1];
            }
        }
        
        return dp[rows-1][columns-1];
    }
    
	//入口方法 main
	public static void main(String[] args) {
		int[][] obstacleGrid = {
   
   {0,0,0},{0,1,0},{0,0,0}};
		int uniquePathsWithObstacles = uniquePathsWithObstacles(obstacleGrid);
		System.out.println(uniquePathsWithObstacles);
	}
}
输出结果2

Guess you like

Origin blog.csdn.net/fxjzzyo/article/details/88994120