leetcode-62-mid-不同路径(动态规划经典例子)

题目描述

一个机器人位于一个 m x n 网格的左上角 。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。

问总共有多少条不同的路径?

分析

  • 问题等价于在笛卡尔坐标系下,从(m,n)到(1,1)进行移动操作,其中移动操作只为左移一格或下移一格。

  • 从(m,n)到(1,1)的移动:在(m,n)处只能移动到(m-1,n)或(m,n-1);

    设表示从(m,n)移动到(1,1)所有的路径数目,其中。

解题思路: 递归

算法

func ( m , n ) :
    if m == 1 or m == 1 :
        return 1
    
    left = f( m-1, n )
    down = f( m, n-1 )
    return left+down

不需要特殊数据结构

代码

class Solution{
public :
    int uniquePaths( int m, int n ){
        if ( m == 1 || n == 1 ){
            return 1 ;
        }
        int left = uniquePaths( m-1, n );
        int down = uniquePaths( m, n-1 ) ;
        return left + down
    }
};

问题在于这样的递归解法中,计算量成指数增长,需要量级的计算。经典例子如:计算斐波那契数列的第n个值

使用动态规划(DP,自底向上)可以避免重复计算。

解题思路:动态规划

算法

arr:
    二维数组,arr[i-1,j-1]存储从(i,j)到(1,1)的路径总数
初始化:
    arr[0][:] = 1
    arr[:][0] = 1
迭代计算:
    for i = 1 to m :
        for j = 1 to n :
            arr[i][j] = arr[i-1][j] + arr[i][j-1] 
    return arr[m-1][n-1]

数据结构

使用可随机访问的顺序表:vector

代码


class Solution {
public:
    int uniquePaths(int m, int n) {
        // 存储结构初始化
        vector> arr ;
        for ( int i = 0 ; i < m ; ++ i ){
            vector tmp(n) ;
            arr.push_back( tmp ) ;
        }
        for ( int i = 0 ; i < m ; ++ i ){
            arr[i][0] = 1 ;
        }
        for ( int j = 0 ; j < n ; ++ j ){
            arr[0][j] = 1 ;
        }

        // dp迭代过程
        for ( int i = 1 ; i < m ; ++ i ){
            for ( int j = 1 ; j < n ; ++ j ){
                arr[i][j] = arr[i-1][j] + arr[i][j-1] ;
            }
        }
        return arr[m-1][n-1] ;
    }
};

相关问题与感想

记得刚接触编程的时候遇到的一个问题,在做这道题的时候突然想起来,和这道题是一样的,分享给大家。

有m个1和n个0,请问有多少中不同的组合方式?

对于任意组合方式,考虑两种情况:最后一个字符是0,最后一个字符是1

两道题目不能说是十分相似,简直是一模一样。可以将向下移动看作是1,向左移动看作是0.


PS.

  1. 相比较于其他已有的leetcode刷题笔记,我希望能够提供相关的解题分析和部分相关问题的链接,使得大家能获得一个较好的分析与相关问题的比较。

  2. 偶尔会进行类似题目的总结工作,有需要的读者可以对这份工作进行关注。

  3. 如果你发现有相关的错误或者表述不当不清晰的地方,请进行评论,我会尽快进行核对勘正。

你可能感兴趣的:(leetcode-62-mid-不同路径(动态规划经典例子))