算法思想一:动态规划

解题思路:

简单的动态规划,直接走就行了,
1、当只有一行的数据只能右边走所以数据只跟左边的数据有关
2、当只有一列的数据只能从上面往下走,只跟上面数据有关
3、其他情况可以来自三个方向,上面,下面,左上来计算

算法流程:

1、两层遍历矩阵 row属于【0,N】,col 属于【0,M】

    1、第一行的只能左边来,动态方程:

    2、第一列只能上面来,动态方程:

    3、其他方式有两种 从左上,动态方程:

2、最后返回

图解:

代码展示:

JAVA版本

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param presentVolumn int整型二维数组 N*M的矩阵,每个元素是这个地板砖上的礼物体积
     * @return int整型
     */
    public int selectPresent (int[][] presentVolumn) {
        // write code here
        // 初始化
        int N=presentVolumn.length;
        if(N==0) return 0;
        int M=presentVolumn[0].length;
        // 双层循环
        for(int row=0;row<N;row++){
            for (int col=0;col<M;col++){
                //Default state
                if(row==0&&col==0) continue;
                //第一行的只能左边来
                if(row==0)
                    presentVolumn[row][col]+=presentVolumn[row][col-1];
                //第一列只能上面来
                if(col==0)
                    presentVolumn[row][col]+=presentVolumn[row-1][col];
                //其他方式有两种 从左上
                if(col!=0&&row!=0){
                    presentVolumn[row][col]+=Math.min(Math.min(presentVolumn[row-1][col],presentVolumn[row][col-1]),presentVolumn[row-1][col-1]);
                }
            }
        }
        return presentVolumn[N-1][M-1];
    }
}

复杂度分析

时间复杂度:N M表示二维矩阵的大小,双层遍历时间

空间复杂度:未使用额外空间

算法思想二:动态规划+dfs

解题思路:

此方法和方法一有同样的解题思路,不同点在于方法一主要采用双层遍历进行动态方程的更新计算,方法二是通过深度优先遍历递归进行动态方程计算

主要是通过深度优先遍历dfs实现向右、向下、右下行走过程

代码展示:

Python版本

class Solution:
    def selectPresent(self , presentVolumn ):
        # write code here
        h = len(presentVolumn)
        if h == 0:
            return 0
        w = len(presentVolumn[0])
        if w == 0:
            return 0
        # 初始化dp数组
        dp = [[-1 for i in range(w)] for j in range(h)]
        dp[0][0] = presentVolumn[0][0]
        def dfs(i,j):
            # 最小值
            if dp[i][j] != -1:
                return dp[i][j]
            # 只有一列数据
            if i == 0 and j > 0:
                dp[0][j] = dfs(0, j-1) + presentVolumn[0][j]
            # 只有一行数据
            if i > 0 and j == 0:
                dp[i][0] = dfs(i-1, 0) + presentVolumn[i][0]
            if i > 0 and j > 0:
                # 递归方程
                dp[i][j] = min(dfs(i-1,j), dfs(i,j-1), dfs(i-1,j-1)) + presentVolumn[i][j]
            return dp[i][j]
        # 递归
        res = dfs(h-1,w-1)
        return res

复杂度分析

时间复杂度:N M表示二维矩阵的大小,深度递归时间

空间复杂度:dp数组占用空间