zoukankan      html  css  js  c++  java
  • leetcode面试准备:Triangle

    leetcode面试准备:Triangle

    1 题目

    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).

    接口:public int minimumTotal(List<List<Integer>> triangle)

    2 思路

    题意

    注意是三角形,第i层选了j位置的数,在第i + 1层只能够选jj + 1层的数。

    这是一道动态规划的题目,求一个三角形二维数组从顶到低端的最小路径和。思路是维护到某一个元素的最小路径和,那么在某一个元素i,j的最小路径和就是它上层对应的相邻两个元素的最小路径和加上自己的值,递推式是sum[i][j]=min(sum[i-1][j-1],sum[i-1][j])+triangle[i][j]。最后扫描一遍最后一层的路径和,取出最小的即可。每个元素需要维护一次,总共有1+2+...+n=n*(n+1)/2个元素,所以时间复杂度是O(n^2)。而空间上每次只需维护一层即可(因为当前层只用到上一层的元素),所以空间复杂度是O(n)。

    上述代码实现时要注意每层第一个和最后一个元素特殊处理一下。

    换个角度考虑一下,如果这道题不自顶向下进行动态规划,而是放过来自底向上来规划,递归式只是变成下一层对应的相邻两个元素的最小路径和加上自己的值,原理和上面的方法是相同的,这样考虑到优势在于不需要最后对于所有路径找最小的,而且第一个元素和最后元素也不需要单独处理了,所以代码简洁了很多。代码如下:

    3 代码

        // 从上往下想
    	public int minimumTotal(List<List<Integer>> triangle) {
    		int size = triangle.size();
    		if (size == 0)
    			return 0;
    		int[] sum = new int[size];
    		sum[0] = triangle.get(0).get(0);
    		for (int i = 1; i < size; i++) {
    			int level = i;
    			sum[i] = sum[i - 1] + triangle.get(i).get(i);
    			for (int j = level - 1; j >= 1; j--) {
    				sum[j] = Math.min(sum[j - 1], sum[j]) + triangle.get(i).get(j);
    			}
    			sum[0] = sum[0] + triangle.get(i).get(0);
    		}
    
    		// 遍历sum,求最小值
    		int min = Integer.MAX_VALUE;
    		for (int s : sum) {
    			min = Math.min(s, min);
    		}
    		return min;
    	}
    
    	// 从下往上想
    	public int minimumTotal1(List<List<Integer>> triangle) {
    		int size = triangle.size();
    		if (size == 0)
    			return 0;
    		int[] sum = new int[size];
    		for (int i = 0; i < size; i++) {
    			sum[i] = triangle.get(size - 1).get(i);
    		}
    		for (int i = size - 2; i >= 0; i--) {
    			int level = i;
    			for (int j = 0; j <= level; j++) {
    				sum[j] = Math.min(sum[j], sum[j + 1]) + triangle.get(i).get(j);
    			}
    		}
    		return sum[0];
    	}
    

    4 总结

    一维DP。模型简单,比较适合在电面中出现。

  • 相关阅读:
    C++11的enum class & enum struct和enum
    c++11 中成员变量初始化的顺序
    c++11 lambda
    Java-NIO
    .Net之路(十五)图解LoadRunner压力測试
    activiti入门3排他网关,并行网管,包括网关,事件网关
    [移动端]移动端上遇到的各种坑与相对解决方式
    《软件调试艺术》读后感四
    [C++设计模式] command 命令模式
    iOS学习笔记23-音效与音乐
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/4802811.html
Copyright © 2011-2022 走看看