LeetCode 120 三角形最小路径和

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

示例 1:

输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
   2
  3 4
 6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

示例 2:

输入:triangle = [[-10]]
输出:-10

提示:

  • 1 <= triangle.length <= 200
  • triangle[0].length == 1
  • triangle[i].length == triangle[i – 1].length + 1
  • -10^4 <= triangle[i][j] <= 10^4

解题:

func minimumTotal(triangle [][]int) int {
	if triangle == nil {
		return 0
	}
	n := len(triangle)
	for i := 1; i < n; i++ {
		lv := len(triangle[i]) - 1
		triangle[i][0] += triangle[i-1][0]
		for j := 1; j < lv; j++ {
			triangle[i][j] += min(triangle[i-1][j-1], triangle[i-1][j])
		}
		triangle[i][lv] += triangle[i-1][lv-1]
	}
	minNum := math.MaxInt
	for _, v := range triangle[n-1] {
		if v < minNum {
			minNum = v
		}
	}
	return minNum
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

官方解答:

1.动态规划

func minimumTotal(triangle [][]int) int {
	n := len(triangle)
	f := make([][]int, n)
	for i := 0; i < n; i++ {
		f[i] = make([]int, n)
	}
	f[0][0] = triangle[0][0]
	for i := 1; i < n; i++ {
		f[i][0] = f[i-1][0] + triangle[i][0]
		for j := 1; j < i; j++ {
			f[i][j] = min(f[i-1][j-1], f[i-1][j]) + triangle[i][j]
		}
		f[i][i] = f[i-1][i-1] + triangle[i][i]
	}
	ans := math.MaxInt32
	for i := 0; i < n; i++ {
		ans = min(ans, f[n-1][i])
	}
	return ans
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

2.动态规划 + 空间优化

func minimumTotal(triangle [][]int) int {
	n := len(triangle)
	f := [2][]int{}
	for i := 0; i < 2; i++ {
		f[i] = make([]int, n)
	}
	f[0][0] = triangle[0][0]
	for i := 1; i < n; i++ {
		curr := i % 2
		prev := 1 - curr
		f[curr][0] = f[prev][0] + triangle[i][0]
		for j := 1; j < i; j++ {
			f[curr][j] = min(f[prev][j-1], f[prev][j]) + triangle[i][j]
		}
		f[curr][i] = f[prev][i-1] + triangle[i][i]
	}
	ans := math.MaxInt32
	for i := 0; i < n; i++ {
		ans = min(ans, f[(n-1)%2][i])
	}
	return ans
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

优化

func minimumTotal(triangle [][]int) int {
	n := len(triangle)
	f := make([]int, n)
	f[0] = triangle[0][0]
	for i := 1; i < n; i++ {
		f[i] = f[i-1]+triangle[i][i]
		for j := i - 1; j> 0;j-- {
			f[j] = min(f[j-1], f[j])+triangle[i][j]
		}
		f[0] += triangle[i][0]
	}
	ans := math.MaxInt32
	for i := 0; i < n; i++ {
		ans = min(ans, f[i])
	}
	return ans
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注