动态规划题目

1.Triangle

1.1 题目描述

  1. description:Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

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

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

1.2 分析和解答

问题描述:这是一个求最小路径和的题目。概念"路径和",太直观就不定义了。

1.2.1 概要分析

  1. 是求最值题:值不是现成的,需要构造。

    1. 最值题的最笨解法是构造出所有的值,然后打擂台式遍历一遍得最值。
    2. 最值是最大的那个局值,所以最值题有天然的子问题特性(可能不是很明显)
  2. 具有子问题特性

    1. 数据是一个树形结构,虽然不是用链表形式的二叉树。树形结构的题都具有
      子问题特性,因为树本身的定义就是一个递归定义。递归和子问题特性是神似。
  3. 这个题目太简单,就直接写出递归方程吧。

    1. 定义1:V(i,j)表示结点(i,j)的值。
    2. 定义2:S(i,j)为以(i,j)为根的树的最小路径和。这个定义就是原问题,有时候 以原问题直接做定义不太好继续分析,那时候就需要下一个相近的定义,见例子[].
    3. 递归公式:
      S ( i , j ) = V ( i , j ) + M i n ( S ( i + 1 , j ) , S ( i + 1 , j + 1 ) ) S_{(i,j)} = V_{(i,j)} + Min( S_{(i+1, j)}, S_{(i+1, j+1)}) S(i,j)=V(i,j)+Min(S(i+1,j),S(i+1,j+1))

1.2.1 递归解法

    /**
     * 算法没问题,递归调用,写法简单扼要,但是会超时
     * @param triangle
     * @param level    当前层数,从0开始计数
     * @param column   当前index,索引嘛,当然从0开始计数了
     * @return 返回以结点(level,column)为子树的小路径和.
     */
    private int findMinPathSum(List<List<Integer>> triangle, int level, int column) {

        if (level == triangle.size() - 1) {
            return triangle.get(level).get(column);
        }

        return triangle.get(level).get(column) +
                Math.min(findMinPathSum(triangle, level + 1, column),
                        findMinPathSum(triangle, level + 1, column + 1));

    }
  1. 算法分析
    1. 优点:代码形式和递归公式高度统一;
    2. 缺点:调用超时;调用栈的空间复杂度不能忽略。

1.2.2 自底向上的解法

    /**
     * 备忘录法,其中用输入数据做了'数据空间',即空间复杂度为O(1),要比要求的O(n)要厉害的多
     * 相关题目:
     * Partition to K Equal Sum Subsets
     * Image Overlap
     * Odd Even Jump
     * @param triangle
     * @return 最小路径和
     */
    public int minimumTotal(List<List<Integer>> triangle) {

        if (triangle.size() == 0) {
            return 0;
        }
        if (triangle.get(0).size() == 0) {
            return 0;
        }
        //从最后一行开始
        for (int i = triangle.size() - 1; i >= 0; i--) {

            for (int j = 0; j < triangle.get(i).size(); j++) {

                Integer value = triangle.get(i).get(j);
                if (i == triangle.size() - 1) {
                    continue;
                } else {
                    int minPath = Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1));
                    triangle.get(i).set(j, value + minPath);
                }
            }
        }
        return triangle.get(0).get(0);
    }

1.3 参考文献

  1. 在csdn上插入公式:优快云-Markdown编辑器-数学公式编写
  2. 在线公式编辑:private.codecogs.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值