zoukankan      html  css  js  c++  java
  • 【LeetCode-回溯/动态规划】不同路径

    题目描述

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
    机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
    问总共有多少条不同的路径?

    示例:

    输入: m = 3, n = 2
    输出: 3
    解释:
    从左上角开始,总共有 3 条路径可以到达右下角。
    1. 向右 -> 向右 -> 向下
    2. 向右 -> 向下 -> 向右
    3. 向下 -> 向右 -> 向右
    
    输入: m = 7, n = 3
    输出: 28
    

    说明:

    • 1 <= m, n <= 100
    • 题目数据保证答案小于等于 2 * 10 ^ 9

    题目链接: https://leetcode-cn.com/problems/unique-paths/

    思路1

    使用回溯来做,代码如下:

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            int ans = 0;
            int curRow = 0, curCol = 0;
            vector<vector<int>> visit(m, vector<int>(n, 0));
            visit[curRow][curCol] = 1;
            dfs(curRow, curCol, m, n, visit, ans);
            return ans;
        }
    
        int dirs[2][2] = {{1,0}, {0, 1}};
        void dfs(int curRow, int curCol, int m, int n, vector<vector<int>>& visit, int& ans){
            if(curRow==m-1 && curCol==n-1){
                ans++;
                return;
            }
    
            for(int i=0; i<2; i++){
                int nextRow = curRow + dirs[i][0];
                int nextCol = curCol + dirs[i][1];
                if(nextRow>=0 && nextRow<m && nextCol>=0 && nextCol<n){
                    if(!visit[nextRow][nextCol]){
                        visit[nextRow][nextCol] = 1;
                        dfs(nextRow, nextCol, m, n, visit, ans);
                        visit[nextRow][nextCol] = 0;
                    }
                }
            }
    
        }
    };
    // 超时
    

    该方法超时未通过。

    思路2

    使用动态规划来做。

    • 状态定义:dp[i][j]表示从起点到位置(i,j)的最大路径数。
    • 状态转移方程:由于机器人只能向右或向下走,所以状态转移方程为dp[i][j] = dp[i-1][j] + dp[i][j-1]
    • 特殊情况:如果机器人当前位置在第一行或者第一列时,那么机器人的上一个位置也是在第一行或者第一列,因为在第一行或者第一列时只能朝一个方向走,所以有dp[0][:]=1, dp[:][0]=1。

    代码如下:

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            vector<vector<int>> dp(m, vector<int>(n, 0));
            for(int i=0; i<m; i++) dp[i][0] = 1;
            for(int i=0; i<n; i++) dp[0][i] = 1;
    
            for(int i=1; i<m; i++){
                for(int j=1; j<n; j++){
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
            return dp[m-1][n-1];
        }
    };
    
    • 时间复杂度:O(m×n)
    • 空间复杂度:O(m×n)
  • 相关阅读:
    mysql的安装、启动和基础配置 —— windows版本
    Navicat安装及简单使用
    期货黄金与现货黄金比较
    android 网络编程--socket tcp/ip udp http之间的关系
    socket、tcp、udp、http 的认识及区别
    Android数据传递的五种方法汇总
    android 应用程序Activity之间数据传递与共享的几种途径
    Android数据存储的五种方法汇总
    Android终端与服务器数据传输解决方案
    转载 解决Android与服务器交互大容量数据问题
  • 原文地址:https://www.cnblogs.com/flix/p/12827392.html
Copyright © 2011-2022 走看看