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)
  • 相关阅读:
    Ext Js MVC系列二 利用Application和Viewport进行应用程序初始化和页面布局
    LINQ to Sql系列一 增,删,改
    Ext Js MVC系列一 环境搭建和MVC框架整体认识
    LINQ to Sql系列四 性能优化总结
    SQL基础回顾系列一 单表查询(select语句)
    JSON详解
    公用类库(4) 缓存操作类CacheUtil
    架构设计考虑的问题(出自代码大全II)
    .net自动更新组件Ant
    .net socket在win2008下的吞吐性能报告
  • 原文地址:https://www.cnblogs.com/flix/p/12827392.html
Copyright © 2011-2022 走看看