[LeetCode] 120. Triangle _Medium tag: Dynamic Programming
2019-04-22 04:24 Johnson_强生仔仔 阅读(221) 评论(0) 编辑 收藏 举报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)
0) brute force , T: O(2 ^ h), Time limit Exceeded
class Solution: def minimumTotal(self, triangle: List[List[int]]) -> int: return self.dfs(triangle, 0 , 0) def dfs(self, triangle: List[List[int]], i: int, j: int): if i == len(triangle) - 1: return triangle[i][j] left = self.dfs(triangle, i + 1, j) right = self.dfs(triangle, i + 1, j + 1) return triangle[i][j] + min(left, right)
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(#using just O(n) space)
more compact
class Solution(object): def minimumTotal(self, nums): """ :type triangle: List[List[int]] :rtype: int """ n = len(nums) if n == 0: return 0 mem = [[0] * n for _ in range(2)] for i in range(n - 1, -1, -1): for j in range(len(nums[i])): mem[i%2][j] = nums[i][j] if i == n - 1 else nums[i][j] + min(mem[(i + 1)%2][j], mem[(i + 1)%2][j + 1]) return mem[0][0]