LeetCode每日一题 三角形最小路径和 动态规划(galang)

题目
在这里插入图片描述
分析过程
1.自上而下
还是用到动态规划的思想
1.用 dp(i,j) 表示从三角形顶端,走到坐标 (i,j) 的所有路径中最小的路径和
2.根据题意,坐标 (i,j)只可能由它左上角或右上角走过来,因此这两个点的坐标分别为dp(i-1,j-1),dp(i-1,j)
3.给出dp(i,j) 的状态转移方程,我们只需要对左上角坐标和右上角坐标的最短路径和求较小值,然后再加上坐标 (i,j) 的元素值就可以得到 dp(i,j), 即
dp(i,j) = min(dp(i-1,j-1),dp(i-1,j)) + a(i,j)

考虑以下特殊情况
1.三角形的顶点,状态值 dp(0,0) 就等于它的元素值 a(0,0),
2.三角形的两条边,三角形左边上的每个点都只能由上一行第1个位置走来,因此 dp(i,0) 就等于上一行的 d(i-1,0) 加上当前元素值 a(i,0);而三角形右边上的每个点,都只能由上一行最后一个位置走来,因此状态 dp(i,i) 等于 dp(i-1,i-1) 加上当前元素值 a(i,i)。.

代码

func minimumTotal(triangle [][]int) int {
  n := len(triangle)    // 取出三角形行数
  dp := make([][]int, n) // 定义状态数组dp
  for i := range dp {
    dp[i] = make([]int, n)
  }
  dp[0][0] = triangle[0][0]     //初始化
  for i := 1; i < n; i++ {
    dp[i][0] = dp[i-1][0] + triangle[i][0]  // 第i行首尾两个位置的状态值
    dp[i][i] = dp[pi-1][i-1] + triangle[i][i] //一般情况
    for j := 1; j < i; j++ {
      dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]
    }
  }
  res := dp[n-1][0]         
  for i := 1; i < n; i++ { // i 从1遍历到n-1  
    res = min(min, dp[n-1][i])        // 计算最后一行状态的最小值
  }
  return res 
}

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

2.自下而上
思路基本相同

func minimumTotal(triangle [][]int) int {
	for i:=len(triangle)-2;i>=0;i--{    //i从n-2开始遍历到0
		for j:=0;j<len(triangle[i]);j++{
			triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]) 
		}
	}
	return triangle[0][0]  //循环结束后返回(0,0)
}
func min(a,b int) int{
	if a<b{
		return a
	}
	return b
}

猜你喜欢

转载自blog.csdn.net/qq_46595591/article/details/107334347