当前位置: 首页 > article >正文

算法每日一练 (20)

💢欢迎来到张翊尘的技术站
💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥

文章目录

  • 算法每日一练 (20)
    • 不同路径 II
      • 题目描述
      • 解题思路
      • 解题代码
        • `c/c++`
        • `golang`
        • `lua`

官方站点: 力扣 Leetcode

算法每日一练 (20)

不同路径 II

题目地址: 不同路径 II

题目描述

给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角(即 grid[0][0])。机器人尝试移动到 右下角(即 grid[m - 1][n - 1])。机器人每次只能向下或者向右移动一步。

网格中的障碍物和空位置分别用 10 来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。

返回机器人能够到达右下角的不同路径数量。

测试用例保证答案小于等于 2 * 109

示例 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 == obstacleGrid[i].length
  • 1 <= m, n <= 100
  • obstacleGrid[i][j]01

解题思路

  • 首先根据题意,当二维数组中首个元素 obstacleGrid[0][0] 或者结尾元素 obstacleGrid[m-1][n-1] 为 1 时,表示不可达,直接返回 0 即可。
  • 又根据题意可知,矩阵中的每个节点只能从上面或者左边到达,也就是说到达某个节点的路径数应该是到达上面节点路径数加上达到左边节点的路径数
  • 又因为最上面一层 m = 0 不存在 “上面的节点”;最左边的一列 n = 0 不存在 “左边的节点”,故某个节点在这两种情况下到达只有一种可能。
  • 综上所述,除下 m = 0n = 0 的情况外,其他的节点应该满足如下公式:

d p [ j ] = d p [ j ] + d p [ j − 1 ] dp[j] = dp[j] + dp[j - 1] dp[j]=dp[j]+dp[j1]

  • 创建 dp 辅助数组,首先初始化第一层的每个节点到达的路径数,只有当 obstacleGrid[0][i] 不是 1 并且前一个节点的达到路径数不是 0,那么当前节点的到达路径数就是 1。
  • 紧接着,借助循环从第二层开始,根据上述公式,计算每个节点到达的路径数。需要额外判断 obstacleGrid[i][j] 是否等于 1,如果等于 1 则当前节点的达路径数就是 0。
  • 最终,返回 dp[n - 1] 最后一层的最后一个节点值满足题意的要求。

解题代码

c/c++
#include <vector>

class Solution
{
public:
    int uniquePathsWithObstacles(std::vector<std::vector<int>> &obstacleGrid)
    {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();

        if (obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1)
            return 0;

        std::vector<int> dp(n, 0);
        dp[0] = 1;
        for (int i = 1; i < n; i++)
        {
            if (obstacleGrid[0][i] == 1)
            {
                dp[i] = 0;
                continue;
            }

            if (dp[i - 1] != 0)
                dp[i] = 1;
        }

        for (int i = 1; i < m; i++)
        {
            if (obstacleGrid[i][0] == 1)
                dp[0] = 0;
            for (int j = 1; j < n; j++)
            {
                if (obstacleGrid[i][j] == 1)
                    dp[j] = 0;
                else
                    dp[j] = dp[j] + dp[j - 1];
            }
        }

        return dp[n - 1];
    }
};
golang
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
    m, n := len(obstacleGrid), len(obstacleGrid[0])
	if obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1 {
		return 0
	}
  
	dp := make([]int, n)
	dp[0] = 1

	for i := 1; i < n; i++ {
		if obstacleGrid[0][i] == 1 {
			dp[i] = 0
			continue
		}

		if dp[i-1] != 0 {
			dp[i] = 1
		}
	}

	for i := 1; i < m; i++ {
		if obstacleGrid[i][0] == 1 {
			dp[0] = 0
		}
		for j := 1; j < n; j++ {
			if obstacleGrid[i][j] == 1 {
				dp[j] = 0
			} else {
				dp[j] = dp[j] + dp[j-1]
			}
		}
	}

	return dp[n-1]
}
lua
local function uniquePathsWithObstacles(obstacleGrid)
    local m, n = #obstacleGrid, #obstacleGrid[1]
    if obstacleGrid[1][1] == 1 or obstacleGrid[m][n] == 1 then
        return 0
    end

    local dp = {}
    dp[1] = 1
    for i = 2, n do
        if obstacleGrid[1][i] == 1 then
            dp[i] = 0
            goto continue
        end

        if dp[i - 1] ~= 0 then
            dp[i] = 1
        end
        ::continue::
    end

    for i = 2, m do
        if obstacleGrid[i][1] == 1 then
            dp[1] = 0
        end
        for j = 2, n do
            if obstacleGrid[i][j] == 1 then
                dp[j] = 0
            else
                dp[j] = dp[j] + dp[j - 1]
            end
        end
    end

    return dp[n]
end

🌺🌺🌺撒花!

如果本文对你有帮助,就点关注或者留个👍
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。

在这里插入图片描述


http://www.kler.cn/a/612021.html

相关文章:

  • 容器C++
  • 关于优麒麟ukylin如何更换清华源以及ubuntu24.04安装gcc-i686-linux-gnu找不到包的问题
  • C#中3维向量的实现
  • 【商城实战(74)】数据采集与整理,夯实电商运营基石
  • 使用crontab 每两分钟执行一次 进入 /var/xxx 执行 git pull
  • 力扣 --2712. 使所有字符相等的最小成本
  • 批量处理word里面表格单元格中多余的回车符
  • 【电气设计】接地/浮地设计
  • Spring Boot框架
  • VScode cl配置
  • redis常用部署架构之redis分片集群。
  • 双塔模型2之如何选择正确的正负样本
  • iOS 在collectionView顶部无缝插入数据效果
  • Pydantic Schema生成指南:自定义JSON Schema
  • Kubernetes网络插件选择与区别之Calico网络插件详解 上集
  • 《Python实战进阶》第30集:Scikit-learn 入门:分类与回归模型
  • flutter-第1章-配置环境
  • 我的世界模组开发进阶教程——生物群系
  • python深度评测:5大中文长度计算方案终极对决(你的选择可能一直是错的)
  • 【区块链 + 文化版权】慧形AI 知识分身 | FISCO BCOS 应用案例