【Dynamic Programming】Triangular Matrix

Article directory


Problems such as triangular matrices are mainly to find the minimum distance. Later, when encountering a comparison problem between matrices, grids, and strings, it is difficult to solve or understand with one-dimensional dynamic regression, and you can consider using two-dimensional dynamic regression. Next, we will use the triangular matrix case to introduce the various ideas of the moving return problem.

Bull link

Question: Given a triangle, calculate the minimum path sum from the top to the bottom of the triangle, each step can move to the next row of adjacent numbers, for example, the triangle given is as follows:

[[20],[30,40],[60,50,70],[40,10,80,30]]

The minimum top-to-bottom path sum is 20 + 30 + 50 + 10 = 110.

top down

insert image description here

analysis of idea:

If you want to use the top-down method to find the sum of the shortest paths, you need to find the sum of the minimum paths from the coordinates (0, 0) to (i, j), and finally the last row of the triangular matrix must reach this point. The shortest path sum, just need to traverse the last line and find the smallest path sum to solve the problem

Each element has two moving paths, the coordinates (i, j) can be moved to the coordinates (i+1, j) and (i+1, j+1)

There are three possibilities for moving to coordinates (i, j)

  1. When the column coordinates in the coordinates are 0 (i, 0), the coordinates to move to this point can only be coordinates (i-1, 0)
  2. When the row and column coordinates in the coordinates are the same (such as (1, 1)), only the coordinates (i-1, j-1) can be moved to this coordinate
  3. In other cases, moving to this coordinate has two coordinates (i-1, j-1) and (i-1, j)

Then when finding the shortest path sum, you only need to add the value of the coordinate to the sum of the shortest path before reaching the coordinate

Set the state to F(i,j): the shortest path from the (0,0) coordinate to the (i,j) coordinate and

E.g

F(0,0)= 20;

F(1,0)= F(0,0)+ 30 = 50 ;F(1,1)= F(0,0)+ 40 = 60;

F(2,1) = min(F(1,0),F(1,1))+ 50 = 100;

In summary:

  1. State definition F(i,j): the shortest path from (0,0) coordinates to (i,j) coordinates and
  2. The transition equation between states defines F(i,j):
  • min(F(i-1,j-1),F(i-1,j)) + path[i][j] (0 < j < i)
  • F(i-1,0) + path[i][0] (j == 0)
  • F(i-1,j-1) + path[i][j] (i == j)
  1. State initialization F(0, 0) = path[0][0]
  2. Return the result min(F(row-1, j))
import java.util.*;
public class Solution {
    
    
    public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
    
    
        if(triangle==null||triangle.isEmpty()) return 0;//若出现传入的线性表为空或没有元素的情况,返回0
        int row = triangle.size();//triangle的大小就是三角矩阵的行
        int[][] path = new int[row][row];//定义path二维数组来存放三角矩阵中每个坐标的状态即最短路径和
        path[0][0] = triangle.get(0).get(0);//状态的初始化
        for(int i = 1;i < row;i ++) {
    
    
            for(int j = 0;j <= i;j ++) {
    
    
                if(j == 0) {
    
    
                    path[i][j] = path[i-1][j] + triangle.get(i).get(j);//转移方程的情况二
                } else if(i == j) {
    
    
                    path[i][j] = path[i-1][j-1] + triangle.get(i).get(j);//转移方程的情况三
                }else {
    
    
                    path[i][j] = Math.min(path[i-1][j],path[i-1][j-1]) + triangle.get(i).get(j);
                    //转移方程的情况一
                }
            }
        } 
        int min = path[row-1][0];
        //将三角矩阵状态最后一行的第一个元素当为最小路径和,通过遍历最后一行找到最小的路径和
        for(int j = 1;j < row;j ++) {
    
    
            if(path[row-1][j] < min) 
                min = path[row-1][j]; 
        }
        return min;//返回最小路径和
    }
}

bottom-up

In fact, the bottom-up approach is simpler and easier to understand than the top-down approach

analysis of idea:

In the bottom-up idea, the set state is the shortest distance from the coordinates (i, j) to the last row, which requires the last row of the triangular matrix to remain unchanged (initialization condition). In addition, each element (except the last row) of the triangular matrix has two moving paths, which can avoid the trouble of considering various situations in the transfer equation in the previous idea. The value at the final coordinate (0, 0) is Triangular matrix shortest path sum.

E.g

F(3,0)= 40;F(3,1)=10;

F(2,0) = min(F(3,0),F(3,1))+ 60 = 70;

In summary:

  1. State definition F(i,j): the shortest path from (i,j) coordinates to the last line and

  2. The transition equation between states defines F(i, j): min(F(i+1, j), F(i+1, j+1)) + path[i][j] (0 <= j <= i)

  3. State initialization F(row-1, 0) = path[row-1][j]

  4. Return the result F(0, 0)

import java.util.*;
public class Solution {
    
    
    public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
    
    
        if(triangle==null||triangle.isEmpty()) return 0;//若出现传入的线性表为空或没有元素的情况,返回0
        int row = triangle.size();//triangle的大小就是三角矩阵的行
        int[][] path = new int[row][row];//定义path二维数组来存放三角矩阵中每个坐标的状态即最短路径和
        //状态最后一行的值为三角矩阵最后一行原来的值
        for(int j = 0;j < row;j++) {
    
    
            path[row -1][j] = triangle.get(row -1).get(j); //状态的初始化
        }
        //从倒数第二行开始
        for(int i = row-2;i >= 0;i--) {
    
    
            for(int j = 0;j <= i;j++) {
    
    
                path[i][j] = Math.min(path[i+1][j],path[i+1][j+1]) + triangle.get(i).get(j);//状态转移
            }
        }
        return path[0][0];//返回最后结果
    }
}

O(N) space

In fact, this can be done with just O(N) extra space, where N is the total number of rows in the triangle.

The main idea is the same as the bottom-up idea, but the storage method is different, and the state of each coordinate is no longer placed in the array separately. Here we choose to use a one-dimensional array whose size is the number of rows of a triangular matrix to store the state.

insert image description here

import java.util.*;
public class Solution {
    
    
   public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
    
    
       if(triangle==null||triangle.size()==0){
    
    
           return 0;
       }
       int row=triangle.size();
       int[]path=new int[row];
       //初始化状态
       for(int j=0;j<row;j++){
    
    
           path[j]=triangle.get(row-1).get(j);
       }
       for(int i=row-2;i>=0;i--){
    
    
           for(int j=0;j<=i;j++){
    
    
               path[j]=triangle.get(i).get(j)+Math.min(path[j],path[j+1]);//状态转移
           }
       }
       return path[0];//返回结果
   }
}

Finish!

Guess you like

Origin blog.csdn.net/weixin_46103589/article/details/121908280