- 问题描述:
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. - 问题解析:感觉也这道题虽然是数组,但可以和数组没多大关系,比如直接在原始的triangle上进行操作,这样反而不需要O(n)的空间。好了,开始解析:首先提取出状态转移方程:
path[i][j] = min(path[i-1][j-1], path[i-1][j]) + triangle[i][j] (triangle是个List,但这里将它当做二维数组来看);
首先想到的是直接定义一个二维数组自顶向下不断搜索即可。但是我们观察到实际上当前的状态只和上一层的状态有关。所以我们只需一个临时数组记录上一层的状态,然后迭代计算,这样只需要一个临时数组加一个状态数组,然后在状态数组和临时数组不断转化即可。然而,继续往下考虑,实际上当前的状态只和上一层的相邻数组的转台有关。我们用两个边路temp1和temp2记录上一层的相邻状态,然后不断更新这个值。代码如下:
其中,path[i][j],代表搜索到triangle的第i行第j列。这个方程式意义是很明显的。就是当前的最小路径和对于上一层相邻的最小路径和加上当前的路径。然后不断更新即可。此外,这个题也可以直接在List上进行操作,这样反而不需要记录临时变量。public class Solution { public int minimumTotal(List<List<Integer>> triangle) { if(triangle == null ||triangle.isEmpty()) return 0; int n = triangle.size(), minPath = Integer.MAX_VALUE, temp1,temp2; if(n == 1) return triangle.get(0).get(0); int[] path = new int[n]; path[0] = triangle.get(0).get(0); for(int i = 1; i < n; i++){ temp1 = path[0]; temp2 = path[1]; minPath = Integer.MAX_VALUE; for(int j = 0; j < i + 1; j++){ if(j == 0) path[j] += triangle.get(i).get(j); else if (j == i) path[j] = temp1 + triangle.get(i).get(j); else { path[j] = Math.min(temp1, temp2) + triangle.get(i).get(j); temp1 = temp2; if(j < n-1) temp2 = path[j+1]; } minPath = Math.min(path[j],minPath); } } return minPath; } }