LeetCode 120. Triangle 三角形

157 阅读1分钟

leetcode.com/problems/tr…

Discuss:www.cnblogs.com/grandyang/p…

Given a triangle array, return the minimum path sum from top to bottom.

For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row.

 

Example 1:

Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
   2
  3 4
 6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).

Example 2:

Input: triangle = [[-10]]
Output: -10

 

Constraints:

  • 1 <= triangle.length <= 200
  • triangle[0].length == 1
  • triangle[i].length == triangle[i - 1].length + 1
  • -104 <= triangle[i][j] <= 104

 

Follow up:  Could you do this using only O(n) extra space, where n is the total number of rows in the triangle?

解法一:

使用动态规划。我们可以复制三角形最后一行,作为用来更新的一维数组。然后逐个遍历这个 DP 数组,对于每个数字,和它之后的元素比较选择较小的再加上面一行相邻位置的元素做为新的元素,然后一层一层的向上扫描,整个过程和冒泡排序的原理差不多,最后最小的元素都冒到前面,第一个元素即为所求。 状态转移方程为:

tMinArray[j] = min(tMinArray[j], tMinArray[j+1]) + triangle[i][j]

代码如下:

class Solution {
    fun minimumTotal(triangle: List<List<Int>>): Int {
        val tMinArray: MutableList<Int> = triangle[triangle.size - 1].toMutableList()
        for (i in triangle.size - 2 downTo 0) {
            for (j in triangle[i].indices) {
                tMinArray[j] = Math.min(tMinArray[j], tMinArray[j + 1]) + triangle[i][j]
            }
        }
        return tMinArray[0]
    }
}

解法二:

我们可以直接复用 triangle 数组,一层一层的累加下来,从而使得 triangle[i][j] 是从最顶层到 (i, j) 位置的最小路径和,那么我们如何得到状态转移方程呢?其实也不难,因为每个结点能往下走的只有跟它相邻的两个数字,那么每个位置 (i, j) 也就只能从上层跟它相邻的两个位置过来,也就是 (i-1, j-1) 和 (i-1, j) 这两个位置,那么状态转移方程为:

triangle[i][j] + = min(triangle[i - 1][j - 1], triangle[i - 1][j])

我们从第二行开始更新,注意两边的数字直接赋值上一行的边界值,那么最终我们只要在最底层找出值最小的数字,就是全局最小的路径和啦,代码如下:

class Solution {
    fun minimumTotal(triangle: List<List<Int>>): Int {
        val mutableTriangle = mutableListOf<MutableList<Int>>()
        triangle.forEach {
            mutableTriangle.add(it.toMutableList())
        }
        for (i in 1 until mutableTriangle.size) {
            for (j in mutableTriangle[i].indices) {
                if (j == 0) {
                    mutableTriangle[i][j] += mutableTriangle[i - 1][j]
                } else if (j == triangle[i].size - 1) {
                    mutableTriangle[i][j] += mutableTriangle[i - 1][j - 1]
                } else {
                    mutableTriangle[i][j] += Math.min(mutableTriangle[i - 1][j - 1], mutableTriangle[i - 1][j])
                }
            }
        }

        mutableTriangle[mutableTriangle.size - 1].sort()
        return mutableTriangle[mutableTriangle.size - 1][0]
    }
}