📑 题目:120. 三角形最小路径和

🚀 本题 LeetCode 传送门

题目大意

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

解题思路

  • 求出从三角形顶端到底端的最小和。要求最好用 O(n) 的时间复杂度。
  • 这一题最优解是不用辅助空间,直接从下层往上层推。普通解法是用二维数组 DP,稍微优化的解法是一维数组 DP。解法如下:

代码

  1. package leetcode
  2. import (
  3. ""math""
  4. )
  5. // 解法一 倒序 DP,无辅助空间
  6. func minimumTotal(triangle [][]int) int {
  7. if triangle == nil {
  8. return 0
  9. }
  10. for row := len(triangle) - 2; row >= 0; row-- {
  11. for col := 0; col < len(triangle[row]); col++ {
  12. triangle[row][col] += min(triangle[row+1][col], triangle[row+1][col+1])
  13. }
  14. }
  15. return triangle[0][0]
  16. }
  17. // 解法二 正常 DP,空间复杂度 O(n)
  18. func minimumTotal1(triangle [][]int) int {
  19. if len(triangle) == 0 {
  20. return 0
  21. }
  22. dp, minNum, index := make([]int, len(triangle[len(triangle)-1])), math.MaxInt64, 0
  23. for ; index < len(triangle[0]); index++ {
  24. dp[index] = triangle[0][index]
  25. }
  26. for i := 1; i < len(triangle); i++ {
  27. for j := len(triangle[i]) - 1; j >= 0; j-- {
  28. if j == 0 {
  29. // 最左边
  30. dp[j] += triangle[i][0]
  31. } else if j == len(triangle[i])-1 {
  32. // 最右边
  33. dp[j] += dp[j-1] + triangle[i][j]
  34. } else {
  35. // 中间
  36. dp[j] = min(dp[j-1]+triangle[i][j], dp[j]+triangle[i][j])
  37. }
  38. }
  39. }
  40. for i := 0; i < len(dp); i++ {
  41. if dp[i] < minNum {
  42. minNum = dp[i]
  43. }
  44. }
  45. return minNum
  46. }