LeetCode 62. Unique Paths

文章目录

  • 题目描述
  • 知识点
  • 结果
  • 实现
    • 码前思考
    • 代码实现
    • 码后反思

题目描述

LeetCode 62. Unique Paths_第1张图片

知识点

动态规划

结果

LeetCode 62. Unique Paths_第2张图片

实现

码前思考

  1. 今天一天都在写动态规划,写的脑子有些迷迷糊糊的,去看了一篇文章——动态规划解题套路框架。虽然还是一些概念,但是温故而知新,我更加深入的了解了重叠子问题最优子结构
  2. 这道题目应该不能算严格意义上的动态规划,因为它没有体现最优的概念,动态规划问题一般是用来求解最优化问题的。但是,这道题目和斐波拉契数列很像,还是把它看作动态规划吧。参考之前看的那篇文章的思路,我尝试使用解动态规划问题的框架来思考:
  3. 划分子问题:求到点 ( i , j ) (i,j) (i,j)的独立路径,由于到点 ( i , j ) (i,j) (i,j)只能由 ( i − 1 , j ) (i-1,j) (i1,j) ( i , j − 1 ) (i,j-1) (i,j1)而来,那么到 ( i , j ) (i,j) (i,j)的独立路径就是到 ( i − 1 , j ) (i-1,j) (i1,j) ( i , j − 1 ) (i,j-1) (i,j1)的独立路径之和,可以分析到 ( i − 1 , j ) (i-1,j) (i1,j) ( i , j − 1 ) (i,j-1) (i,j1)的独立路径是不会重叠的,它们是独立的。
    综上,最优子结构中的划分子问题解决,通常这一步很关键,一般的话,我都是先用暴力来试探怎么求解问题,看能不能通过暴力来发现子问题的存在,这道题里由子问题到原问题比较简单,只是加法,在难一点的动态规划问题中情况会复杂很多,通常会涉及到各种iffor
  4. 确定状态:上述原问题和子问题的区别在于坐标,因此状态是坐标
  5. 确定dp数组的意义:通常它的含义就是问题,因此是到坐标 ( i , j ) (i,j) (i,j)的独立路径数
  6. 确定边界条件:边界条件通常是数组的边界出现在越界的地方,这里就是第一列和第一行的dp值要初始化为1。
  7. 综上4点,我们就能得到状态转移方程了。

代码实现

class Solution {
public:
    int uniquePaths(int m, int n) {
        //dp数组
        vector<vector<int>> dp(n+1,vector<int>(m+1,0));

        dp[1][1] = 1;

        //进行初始化,base case,虽然最早写,但是分析时是最晚分析的
        for(int j=2;j<=m;j++){
            dp[1][j] = 1;
        }
        for(int i=2;i<=n;i++){
            dp[i][1] = 1;
        }

        //开始进行递推求解,一行一行算
        for(int i=2;i<=n;i++){
            for(int j=2;j<=m;j++){
                dp[i][j] = dp[i][j-1]+dp[i-1][j];
            }
        }

        return dp[n][m];        
    }
};

码后反思

  1. 唉,做动态规划的题目要脑袋里面时刻清醒,要记住动态规划来自于暴力穷举,只是对暴力穷举进行了优化,我们可以先从暴力入手,从暴力里面抽取动态规划思想
  2. 加油,继续努力,多实践,多反思,多总结。

你可能感兴趣的:(#,动态规划,动态规划)