# [120. Triangle](https://leetcode.com/problems/triangle/) ## 题目 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. ## 题目大意 给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。 ## 解题思路 - 求出从三角形顶端到底端的最小和。要求最好用 O(n) 的时间复杂度。 - 这一题最优解是不用辅助空间,直接从下层往上层推。普通解法是用二维数组 DP,稍微优化的解法是一维数组 DP。解法如下: ## 代码 ```go package leetcode import ( "math" ) // 解法一 倒序 DP,无辅助空间 func minimumTotal(triangle [][]int) int { if triangle == nil { return 0 } for row := len(triangle) - 2; row >= 0; row-- { for col := 0; col < len(triangle[row]); col++ { triangle[row][col] += min(triangle[row+1][col], triangle[row+1][col+1]) } } return triangle[0][0] } // 解法二 正常 DP,空间复杂度 O(n) func minimumTotal1(triangle [][]int) int { if len(triangle) == 0 { return 0 } dp, minNum, index := make([]int, len(triangle[len(triangle)-1])), math.MaxInt64, 0 for ; index < len(triangle[0]); index++ { dp[index] = triangle[0][index] } for i := 1; i < len(triangle); i++ { for j := len(triangle[i]) - 1; j >= 0; j-- { if j == 0 { // 最左边 dp[j] += triangle[i][0] } else if j == len(triangle[i])-1 { // 最右边 dp[j] += dp[j-1] + triangle[i][j] } else { // 中间 dp[j] = min(dp[j-1]+triangle[i][j], dp[j]+triangle[i][j]) } } } for i := 0; i < len(dp); i++ { if dp[i] < minNum { minNum = dp[i] } } return minNum } ```