码迷,mamicode.com
首页 > 其他好文 > 详细

Triangle

时间:2015-12-25 01:14:19      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:

?

package cn.edu.xidian.sselab.array;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author zhiyong wang
 * title:    Triangle
 * content:
 *         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.
 *
 */
public class Triangle {

    //上来自己没有理解题意,以为是找到每一行的最小数据,然后求和,所以得到下面的结果,
    //后来发现是错误的
    public int minimumTotal(List<List<Integer>> triangle){
        int length = triangle.size();
//            int[] result = new int[length];
        int result = 0;
        for(int i=0;i<length;i++){
            int width = triangle.get(i).size();
            for(int j=0;j<width-1;j++){
                if(triangle.get(i).get(j) < triangle.get(i).get(j+1)){
                    int big = triangle.get(i).get(j+1);
                    int small = triangle.get(i).get(j);
                    triangle.get(i).set(j, big);
                    triangle.get(i).set(j+1, small);
                }
            }
            result += triangle.get(i).get(width-1);
        }
        System.out.println(result);
        return result;
    }
        
    //参考答案用动态规划,时间复杂度是O(n^2)
    //从第一个元素开始考虑,一直往下走,求出每行每一个点的值,最后对最后一行进行遍历,得到最小的结果
    //不要需要注意第一行(只有一个顶点),每一行的第一个值与最后一个值,不用进行比较,只有一个结果
    //从上到下, 下一行的结果根据上一行的路径累计和而计算。
    //triangle[i][j] += min(triangle[i -1 [j -1 ],triangle[i -1 ][j ] )
    public int minimumTotals(List<List<Integer>> triangle){
        int length = triangle.size();
        List<List<Integer>> result = new ArrayList<List<Integer>>(length);
        for(int i=0;i<length;i++){
            List<Integer> lines = triangle.get(i);
            result.add(new ArrayList<Integer>(lines.size()));//关键所在
            if(i==0){
                //第一行
                result.get(0).add(lines.get(0));
            }else {
                int size = lines.size();
                for(int j=0;j<size;j++){
                    if(j==0){
                        //每一行的第一个数字
                        result.get(i).add(result.get(i-1).get(0) + lines.get(0));
                    }else if(j==size-1){
                        //每一行的最后一个数字
                        result.get(i).add(result.get(i-1).get(j-1) + lines.get(j));
                    }else{
                        if(result.get(i-1).get(j-1) + lines.get(j) > result.get(i-1).get(j) + lines.get(j)){
                            result.get(i).add(result.get(i-1).get(j) + lines.get(j));
                        }else{
                            result.get(i).add(result.get(i-1).get(j-1) + lines.get(j));
                        }
                    }
                }
            }
        }
        int lastLineLength = triangle.get(length-1).size();
        int min = Integer.MAX_VALUE;
        for(int i=0;i<lastLineLength;i++){
            if(min > result.get(length-1).get(i)){
                min =  result.get(length-1).get(i);
            }
        }
        return min;
    }
    
    
    //参考了大神为了不考虑边界问题,转为从下往上进行求解
   /*键之处在于逆向思维。
    * 根据题意会自然而然地想从上而下逐层寻找最优解,但是由于下层元素比上层多,
    * 边界处的计算非常繁琐。但是如果自下而上,逐层计算到当前层的最优解,那么
    * 到达最顶端时,就是所求最优解。
    */
    public int minimumTotal2(List<List<Integer>> triangle){
        int length = triangle.size();
        //首先考虑特殊情况
        if(triangle == null || length == 0)return 0;
        if(length == 1) return triangle.get(0).get(0);
        int[] below = new int[length];//用于保存下一行的最优解,
        int[] cur = new int[length];//用于保存当前行的最优解
        
        //初始化最下面一行的值
        for(int i=0;i<length;i++){
            below[i] = triangle.get(length-1).get(i);
        }
        //自底向上开始求最优解
        for(int i=length-2;i>=0;i--){
            List<Integer> row = triangle.get(i);
            for(int j=0;j<row.size();j++){
                if(below[j] < below[j+1]){
                    cur[j] = below[j] + row.get(j);
                }else{
                    cur[j] = below[j+1] + row.get(j);
                }
            }
            for(int j=0;j<row.size();j++){
                below[j] = cur[j];
            }
        }
        return cur[0];
    }
}

Triangle

标签:

原文地址:http://www.cnblogs.com/wzyxidian/p/5074736.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!