zoukankan      html  css  js  c++  java
  • [LeetCode] 120. 三角形最小路径和

    题目链接 :https://leetcode-cn.com/problems/triangle/

    题目描述:

    给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

    例如,给定三角形:

    [
         [2],
        [3,4],
       [6,5,7],
      [4,1,8,3]
    ]
    

    自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

    说明:

    如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

    思路:

    我的第一个思路是用DFS,遍历所有从上到下的路径,如下图所示:

    def minimumTotal(self, triangle: List[List[int]]) -> int:
            self.res = float("inf")
            row = len(triangle)
            def helper(level, i, j, tmp):
                if level == row:
                    self.res = min(self.res, tmp)
                    return 
                if 0 <= i < len(triangle[level]):
                    helper(level + 1, i, i+1, tmp + triangle[level][i])
                if 0 <= j < len(triangle[level]):
                    helper(level + 1, j, j+1, tmp + triangle[level][j])
            # 层level, 访问下一层两个节点位置i,j , 目前总和tmp
            helper(0, -1, 0, 0)
            return self.res
    

    上面做法遍历所有路径,所以会超时,所以我们采用带记忆的DFS(动态规划的自顶向下),

      def minimumTotal(self, triangle) -> int:
            import functools
            row = len(triangle)
    
            @functools.lru_cache(None)
            def helper(level, i, j):
                if level == row:
                    return 0
                res = 0
                a = float("inf")
                b = float("inf")
                if 0 <= i < len(triangle[level]):
                    a = helper(level + 1, i, i + 1) + triangle[level][i]
                if 0 <= j < len(triangle[level]):
                    b = helper(level + 1, j, j + 1) + triangle[level][j]
                res += min(a, b)
                return res
    
            return helper(0, -1, 0) 
    

    接下来,我们用自底向上动态规划

    我们先用(O(n^2))空间,这样更容易理解

    dp[i][j] 表示到从上到下走到i,j位置最小路径的值.

    动态方程: dp[i][j] = min(dp[i-1][j], dp[i-1][j+1]) + triangle[i][j]

    当然对于第一个和最后一个要单独考虑.

    def minimumTotal(self, triangle: List[List[int]]) -> int:
            n = len(triangle)
            if n == 0:
                return 0
            # 建dp空间
            dp = [[0] * i for i in range(n)]
            dp[0][0] = triangle[0][0]
    
            for i in range(1, n):
                for k in range(i + 1):
                    if k == 0:
                        dp[i][k] = dp[i - 1][k] + triangle[i][k]
                    elif k == i:
                        dp[i][k] = dp[i - 1][k - 1] + triangle[i][k]
                    else:
                        dp[i][k] = min(dp[i - 1][k - 1], dp[i - 1][k]) + triangle[i][k]
            return min(dp[-1])
    

    其实我们dp时候每次只用到上一层数据,如果我们倒着,从底向上可以优化成(O(n))空间的

    def minimumTotal(self, triangle: List[List[int]]) -> int:
            row = len(triangle)
            dp = [0] * row
            for i in range(len(triangle[-1])):
                dp[i] = triangle[-1][i]
            #print(dp)
            for i in range(row - 2, -1, -1):
                for j in range(i + 1):
                    dp[j] = min(dp[j], dp[j + 1]) + triangle[i][j]
            return dp[0]          
    

    java

    class Solution {
        public int minimumTotal(List<List<Integer>> triangle) {
            int row = triangle.size();
            int[] dp = new int[row];
            for (int i = 0; i < row; i++) dp[i] = triangle.get(row - 1).get(i);
            for (int i = row - 2; i >= 0; i--)
                for (int j = 0; j <= i; j++)
                    dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);
            return dp[0];
        }
    }
    
  • 相关阅读:
    centos crash debug
    go get Unknown SSL protocol error in connection to gopkg.in
    Tensorflow serving with Kubernetes
    Spring 集成 Swagger UI
    Docker Registry V2 Garbage Collection
    Docker Registry V2 with Nginx
    Zabbix磁盘性能监控
    Zabbix CPU utilization监控参数
    Windows挂载Gluster复制卷
    Redis持久化存储(三)
  • 原文地址:https://www.cnblogs.com/powercai/p/11129024.html
Copyright © 2011-2022 走看看