zoukankan      html  css  js  c++  java
  • 【leetcode刷题笔记】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.


    题解:典型的动态规划,开始的想法是用一个二维数组sum,sum[i][j]表示从第一行第一列走到(i,j)所得的最小和。那么sum[i,j] = triangle[i,j] + sum[i-1,j-1](注意下表越界判断)。最后返回sum最后一行中最小的元素。

    代码如下:

     1 public class Solution {
     2     public int minimumTotal(List<List<Integer>> triangle) {
     3         if(triangle == null || triangle.size() == 0)
     4             return 0;
     5         
     6         int length = triangle.size();
     7         int[][] sum = new int[length][length];
     8         
     9         for(int i = 0;i < triangle.get(0).size();i++)
    10             sum[0][i]= triangle.get(0).get(i);
    11         
    12         for(int i = 1;i < length;i++){
    13             for(int j = 0;j < triangle.get(i).size();j++){
    14                 int left = j-1>=0?sum[i-1][j-1]:Integer.MAX_VALUE;
    15                 int middle = j>triangle.get(i).size()-2?Integer.MAX_VALUE:sum[i-1][j];
    16                 
    17                 sum[i][j]  = triangle.get(i).get(j) +  Math.min(left, middle); 
    18             }
    19         }
    20         
    21         int answer = Integer.MAX_VALUE;
    22         for(int i = 0;i < triangle.get(length-1).size();i++)
    23             answer = Math.min(answer, sum[length-1][i]);
    24         
    25         return answer;
    26     }
    27 }

    上述的解法是O(n2)的空间复杂度,实际上在计算当前行sum的时候我们只用到了上一行的sum值,所以我们可以只保存上一行元素的sum值。但是有一点要注意,如果直接把sum降维成一维数组并且按照从左往右的顺序计算sum是不正确的。例如如下的例子

    [
         [-1],
        [-2,-3],
    ] 

    在计算第二行的时候,sum=[-1,0],当计算到元素-2所对应的sum时,sum被更新为[-3,0],那么在计算-3所对应的sum的时候需要的上一行元素对应的-1就丢失了,会得到-3对应的sum为-6的错误结果。所以我们在计算当前行元素的时候,要从后往前计算,就不会把计算下一个元素要用到的数据弄丢了。

    最后空间复杂度为O(n)的代码如下:

     1 public class Solution {
     2     public int minimumTotal(List<List<Integer>> triangle) {
     3         if(triangle == null || triangle.size() == 0)
     4             return 0;
     5         
     6         int length = triangle.size();
     7         int[] sum = new int[length];
     8         
     9         for(int i = 0;i < triangle.get(0).size();i++)
    10             sum[i]= triangle.get(0).get(i);
    11         
    12         for(int i = 1;i < length;i++){
    13             for(int j = triangle.get(i).size()-1;j>=0;j--){
    14                 int left = j-1>=0?sum[j-1]:Integer.MAX_VALUE;
    15                 int middle = j>triangle.get(i).size()-2?Integer.MAX_VALUE:sum[j];
    16                 
    17                 sum[j]  = triangle.get(i).get(j) +  Math.min(left, middle); 
    18             }
    19         }
    20         
    21         int answer = Integer.MAX_VALUE;
    22         for(int i = 0;i < triangle.get(length-1).size();i++)
    23             answer = Math.min(answer, sum[i]);
    24         
    25         return answer;
    26     }
    27 }
  • 相关阅读:
    .net GC的工作原理
    ISAPI的作用ASP.NET的HTTP请求的处理方法
    进程和线程
    浅论ViewState及其与Session的关系
    堆和栈的区别
    关于system.resources名称空间引用的问题
    多线程和多进程
    HTTP 状态码含义
    WebView 载入本地的html
    Intentfilter的介绍
  • 原文地址:https://www.cnblogs.com/sunshineatnoon/p/3860303.html
Copyright © 2011-2022 走看看