[LeetCode] 120. Triangle _Medium tag: Dynamic Programming

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

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

The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

Note:

Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

可以用DFS中的divide and conquer来去计算,此时会有O(2^h) 的复杂度,所以可以加上memorize的array去优化时间复杂度。最后时间复杂度为 O(h^2)

同时通过 f[x][y] = nums[x][y] + min(f[x + 1][y], f[x + 1][y + 1])  来得到for loop去循环来得到的结果,其实就是上面那种做法用for loop来写而已。时间复杂度为 O(h^2)

1) 利用DFS, Divide and conquer

class Solution:
    def triangle(self, nums):
        if not nums or len(nums[0]) == 0:
            return 0
        mem = [[None]*len(nums) for _ in range(len(nums))]
        def helper(nums, x, y):
            if x == len(nums) - 1:
                return nums[x][y]
            if mem[x][y] is not None:
                return mem[x][y]
            left = helper(nums, x + 1, y)
            right = helper(nums, x + 1, y + 1)
            mem[x][y] = nums[x][y] + min(left, right)
            return mem[x][y]
        return helper(nums, 0, 0)

2) 利用for loop并且memorize

class Solution:
    def triangle(self, nums):
        if not nums or len(nums[0]) == 0:
            return 0
        length = len(nums)
        mem = [[0]*length for _ in range(length)]
        for i in range(length):
            mem[length - 1][i] = nums[length - 1][i]
        for i in range(length - 2, -1, -1):
            for j in range(len(nums[i])):
                mem[i][j] = nums[i][j] + min(mem[i + 1][j], mem[i + 1][j + 1])
        return mem[0][0]

猜你喜欢

转载自www.cnblogs.com/Johnsonxiong/p/10748061.html