• Triangle


    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];
        }
    }

  • 相关阅读:
    通信收发单元
    WOSA协议(转)
    CcTalk (网络协议)(转)
    0x和H都表示十六进制有什么区别吗?
    select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)
    &是什么运算符(转)
    NDK的Paths and Symbols设定
    android JNI调用(转)
    scrapy-redis基础和介绍
    scrapy-redis介绍(一)
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/5074736.html
Copyright © 2020-2023  润新知