算法leetcode|63. 不同路径 II(rust重拳出击)


文章目录


63. 不同路径 II:

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 "Start" )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 "Finish")。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 10 来表示。

样例 1:

复制代码
输入:
	
	obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
	
输出:
	
	2
	
解释:

	3x3 网格的正中间有一个障碍物。
	从左上角到右下角一共有 2 条不同的路径:
	1. 向右 -> 向右 -> 向下 -> 向下
	2. 向下 -> 向下 -> 向右 -> 向右

样例 2:

复制代码
输入:
	
	obstacleGrid = [[0,1],[0,0]]
	
输出:
	
	1

提示:

  • m == obstacleGrid.length
  • n == obstacleGridi.length
  • 1 <= m, n <= 100
  • obstacleGridij 为 0 或 1

分析:

  • 面对这道算法题目,二当家的再次陷入了沉思。
  • 这道题和62. 不同路径 类似,但是由于有随机位置的障碍物,所以就不能直接用数学的组合数方式求解了。
  • 那么动态规划成了此时的优选。每一个点的不同路径数是到达上面点的不同路径数与到达左面不同路径数的和。我们可以按行从上到下的方式处理(按列从左到右处理也是可以的,但是有些别扭,因为二维数组的第一维是行,第二维是列,习惯上都是按行处理),这样会发现每行只和上一行的结果有关系,所以就不需要 m * n 的额外空间,而只需要 m 的空间,即滚动数组的思想。

题解:

rust:

rust 复制代码
impl Solution {
    pub fn unique_paths_with_obstacles(obstacle_grid: Vec<Vec<i32>>) -> i32 {
        let rows = obstacle_grid.len();
        let cols = obstacle_grid[0].len();
        let mut dp = vec![0; cols];

        if obstacle_grid[0][0] == 0 {
            dp[0] = 1;
        }

        (0..rows).for_each(|r| {
            (0..cols).for_each(|c| {
                if obstacle_grid[r][c] == 1 {
                    dp[c] = 0;
                } else if c > 0 && obstacle_grid[r][c - 1] == 0 {
                    dp[c] += dp[c - 1];
                }
            });
        });

        return dp[cols - 1];
    }
}

go:

go 复制代码
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
    rows, cols := len(obstacleGrid), len(obstacleGrid[0])
	dp := make([]int, cols)

	if obstacleGrid[0][0] == 0 {
		dp[0] = 1
	}

	for r := 0; r < rows; r++ {
		for c := 0; c < cols; c++ {
			if obstacleGrid[r][c] == 1 {
				dp[c] = 0
				continue
			}
			if c > 0 && obstacleGrid[r][c-1] == 0 {
				dp[c] += dp[c-1]
			}
		}
	}

	return dp[cols-1]
}

c++:

cpp 复制代码
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        const int rows = obstacleGrid.size(), cols = obstacleGrid.at(0).size();
        vector<int> dp(cols);

        dp[0] = (obstacleGrid[0][0] == 0);
        for (int r = 0; r < rows; ++r) {
            for (int c = 0; c < cols; ++c) {
                if (obstacleGrid[r][c] == 1) {
                    dp[c] = 0;
                    continue;
                }
                if (c > 0 && obstacleGrid[r][c - 1] == 0) {
                    dp[c] += dp[c - 1];
                }
            }
        }

        return dp.back();
    }
};

python:

python 复制代码
class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        rows, cols = len(obstacleGrid), len(obstacleGrid[0])
        dp = [0] * cols
        if obstacleGrid[0][0] == 0:
            dp[0] = 1
        for r in range(rows):
            for c in range(cols):
                if obstacleGrid[r][c] == 1:
                    dp[c] = 0
                    continue
                if c > 0 and obstacleGrid[r][c - 1] == 0:
                    dp[c] += dp[c - 1]
        return dp[cols - 1]

java:

java 复制代码
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        final int   rows = obstacleGrid.length, cols = obstacleGrid[0].length;
        final int[] dp   = new int[cols];

        if (obstacleGrid[0][0] == 0) {
            dp[0] = 1;
        }

        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                if (obstacleGrid[i][j] == 1) {
                    dp[j] = 0;
                    continue;
                }
                if (j > 0 && obstacleGrid[i][j - 1] == 0) {
                    dp[j] += dp[j - 1];
                }
            }
        }

        return dp[cols - 1];
    }
}

非常感谢你阅读本文~

欢迎【点赞】【收藏】【评论】三连走一波~

放弃不难,但坚持一定很酷~

希望我们大家都能每天进步一点点~

本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


相关推荐
葫芦和十三37 分钟前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗4 小时前
单 Agent 实现模式
后端
IT_陈寒6 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
fliter7 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
fliter8 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪8 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter8 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶9 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿9 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝9 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员