首页 > 代码库 > Triangle
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.
- <span style="font-size:18px;">public class Solution {
- public int minimumTotal(List<List<Integer>> triangle) {
- int num = (triangle.size()+1)*triangle.size()/2;//元素数
- int L = 1;//i节点所在的层数,i节点的左节点是i + L,右节点是i+L+1
- int[] train = new int[num];
- int k = 0;
- for(int i = 0 ; i < triangle.size() ; i++){
- for(int j = 0 ; j < triangle.get(i).size();j++){
- train[k++] = triangle.get(i).get(j);//将列表转存到数组中,方便处理
- }
- }
- //接下来利用树的深度遍历思想寻找最小值
- //int min = 0;
- if(num < 1){//空
- return 0;
- }
- return inorder(train,0,1,0);
- }
- public int inorder(int train[],int index, int L,int min){//参数的意义,train为存储数据的数组,index为要访问数组的下标,L是访问数组的层数,min为从父节点传递下来的最小值
- if(index + L >= train.length){//叶子节点,这棵树是一棵完全二叉树
- return min + train[index];
- }else{//非叶子节点,继续向下传播,
- int left = inorder(train,index + L,L+1,min+train[index]);
- int right = inorder(train,index + L+1,L+1,min+train[index]);
- return left>right ? right : left;
- }
- }
- }</span>
时间超时。。。。
观察发现,其实最终这个三角形是一个完全二叉树的形式,所以最先想到使用树的DFS,遍历完之后就找到了。但是使用树遍历的方式时间超时,所以参考网上的思路,使用动态规划算法,有两种调整方式,自顶向下和自底向上。
我采用的是自顶向下的方式。
首先根据的左右节点的概念,我们发现在数组中第i个节点对应的树中的左右节点分别是i+L和i+L+1,L为i节点所在的层次(不是2i和2i+1,这点需要注意,虽说是完全二叉树的形式,但是不同于完全二叉树)。
那么,知道了上面的关系我们也就知道了迭代公式
d[k + i] = d[k + i ] > d[k]+trian[k + i]? d[k]+trian[k+i]: d[k + i ];// i 节点的左节点
d[k + i + 1] = d[k + i + 1] > d[k]+trian[k + i + 1]? d[k]+trian[k + i + 1]: d[k + i + 1];// i 节点的右节点
- <span style="font-size:14px;">public class Solution {
- public int minimumTotal(List<List<Integer>> triangle) {
- int num = (triangle.size()+1)*triangle.size()/2;//元素数
- int level = triangle.size();//层数
- int L = 1;//i节点所在的层数,i节点的左节点是i + L,右节点是i+L+1
- int[] trian = new int[num];
- int k = 0;
- for(int i = 0 ; i < triangle.size() ; i++){
- for(int j = 0 ; j < triangle.get(i).size();j++){
- trian[k++] = triangle.get(i).get(j);//将列表转存到数组中,方便处理
- }
- }
- if(num < 1){
- return 0;
- }
- int[] d = new int[num];//记录每一个元素对应的最小路径长
- for(int i = 0; i < num ; i ++){
- d[i] = Integer.MAX_VALUE;
- }
- k = 0;
- d[0] = trian[k];
- for(int i = 1 ; i < level ; i ++){
- for(int j = 0 ; j < i ; j ++){
- d[k + i] = d[k + i ] > d[k]+trian[k + i]? d[k]+trian[k+i]: d[k + i ];//左节点
- d[k + i + 1] = d[k + i + 1] > d[k]+trian[k + i + 1]? d[k]+trian[k + i + 1]: d[k + i + 1];//右节点
- k++;
- }
- }
- int min = d[num-1];
- for(int i = num - 2 ; i > num - 1 - level; i --){
- if(min > d[i]){
- min = d[i];
- }
- }
- return min;
- }
- }</span>
Triangle