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

每日一题——不同路径的数目与矩阵最小路径和

机器人路径问题与矩阵最小路径和

    • 1. 机器人路径问题
      • 题目描述
      • 示例
        • 示例 1
        • 示例 2
      • 解题思路
        • 动态规划
      • 代码实现
      • 复杂度分析
    • 2. 矩阵的最小路径和
      • 题目描述
      • 示例
        • 示例 1
        • 示例 2
      • 解题思路
        • 动态规划
      • 代码实现
      • 复杂度分析
    • 总结

1. 机器人路径问题

题目描述

一个机器人在 (m \times n) 大小的地图的左上角(起点)。机器人每次可以向下或向右移动。机器人要到达地图的右下角(终点)。可以有多少种不同的路径从起点走到终点?
在这里插入图片描述
数据范围:
(0 < n, m \leq 100),保证计算结果在 32 位整型范围内。

要求:

  • 空间复杂度:(O(nm))
  • 时间复杂度:(O(nm))
  • 进阶:空间复杂度 (O(1)),时间复杂度 (O(\min(n, m)))

示例

示例 1

输入:
2, 1
返回值:
1

示例 2

输入:
2, 2
返回值:
2


解题思路

动态规划
  1. 定义状态

    • dp[i][j] 表示从起点到位置 (i, j) 的不同路径数。
  2. 状态转移方程

    • 机器人只能向下或向右移动,因此:
      [
      dp[i][j] = dp[i-1][j] + dp[i][j-1]
      ]
  3. 边界条件

    • 当 (i = 1) 或 (j = 1) 时,dp[i][j] = 1,因为只有一条路径(一直向右或一直向下)。
  4. 目标

    • 计算 dp[m][n],即从起点到终点的路径数。

代码实现

#include <stdio.h>
#include <stdlib.h>

int uniquePaths(int m, int n) {
    // 分配动态规划表
    int** dp = (int**)calloc(m + 1, sizeof(int*));
    for (int i = 0; i <= m; i++) {
        dp[i] = (int*)calloc(n + 1, sizeof(int));
    }

    // 初始化边界条件
    for (int i = 1; i <= m; i++) {
        dp[i][1] = 1;
    }
    for (int j = 1; j <= n; j++) {
        dp[1][j] = 1;
    }

    // 填充动态规划表
    for (int i = 2; i <= m; i++) {
        for (int j = 2; j <= n; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
    }

    // 获取结果
    int num = dp[m][n];

    // 释放动态规划表
    for (int i = 0; i <= m; i++) {
        free(dp[i]);
    }
    free(dp);

    return num;
}

复杂度分析

  • 时间复杂度:(O(m \times n)),需要填充 (m \times n) 的动态规划表。
  • 空间复杂度:(O(m \times n)),用于存储动态规划表。

2. 矩阵的最小路径和

题目描述

给定一个 (n \times m) 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。

数据范围:
(1 \leq n, m \leq 500),矩阵中任意值都满足 (0 \leq a_{i,j} \leq 100)。

要求:

  • 时间复杂度:(O(nm))

示例

在这里插入图片描述

示例 1

输入:
[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]
返回值:
12

示例 2

输入:
[[1,2,3],[1,2,3]]
返回值:
7


解题思路

动态规划
  1. 定义状态

    • dp[i][j] 表示从起点到位置 (i, j) 的最小路径和。
  2. 状态转移方程

    • 只能从上方或左方移动,因此:
      [
      dp[i][j] = a[i-1][j-1] + \min(dp[i-1][j], dp[i][j-1])
      ]
  3. 边界条件

    • 当 (i = 1) 且 (j = 1) 时,dp[1][1] = a[0][0]
    • 当 (i = 1) 时,只能从左方移动,dp[1][j] = dp[1][j-1] + a[0][j-1]
    • 当 (j = 1) 时,只能从上方移动,dp[i][1] = dp[i-1][1] + a[i-1][0]
  4. 目标

    • 计算 dp[n][m],即从起点到终点的最小路径和。

代码实现

#include <stdio.h>
#include <stdlib.h>

int minPathSum(int** matrix, int matrixRowLen, int* matrixColLen) {
    int m = matrixRowLen; // 行数
    int n = *matrixColLen; // 列数

    // 分配动态规划表
    int** dp = (int**)calloc(m + 1, sizeof(int*));
    for (int i = 0; i <= m; i++) {
        dp[i] = (int*)calloc(n + 1, sizeof(int));
    }

    // 初始化边界条件
    for (int i = 0; i <= m; i++) {
        dp[i][0] = 65535; // 初始化为一个较大的值
    }
    for (int j = 0; j <= n; j++) {
        dp[0][j] = 65535; // 初始化为一个较大的值
    }
    dp[1][1] = matrix[0][0]; // 特殊处理起点

    // 填充动态规划表
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == 1 && j == 1) {
                continue; // 起点已经初始化
            }
            dp[i][j] = matrix[i - 1][j - 1] + ((dp[i - 1][j] < dp[i][j - 1]) ? dp[i - 1][j] : dp[i][j - 1]);
        }
    }

    // 获取结果
    int num = dp[m][n];

    // 释放动态规划表
    for (int i = 0; i <= m; i++) {
        free(dp[i]);
    }
    free(dp);

    return num;
}

复杂度分析

  • 时间复杂度:(O(m \times n)),需要填充 (m \times n) 的动态规划表。
  • 空间复杂度:(O(m \times n)),用于存储动态规划表。

总结

  • 机器人路径问题:通过动态规划计算从起点到终点的路径数。
  • 矩阵最小路径和:通过动态规划计算从起点到终点的最小路径和。
  • 动态规划是解决路径问题的有效方法,关键在于定义状态和状态转移方程。

相关文章:

  • 性格测评小程序07用户登录
  • 【第14章:神经符号集成与可解释AI—14.2 可解释AI技术:LIME、SHAP等的实现与应用案例】
  • 2025年2月16日笔记
  • NSSCTF Pwn [HUBUCTF 2022 新生赛]singout WP
  • 二〇二四年终总结
  • 搭建Deepseek推理服务
  • dify新版,chatflow对deepseek的适配情况
  • bps是什么意思
  • 网络安全:从攻击到防御的全景解析
  • AI视频创作教程:如何用AI让古画动起来。
  • 动量突破均值回归策略
  • 【PYTORCH】官方的turoria实现中英文翻译
  • 水务+AI应用探索(一)| FastGPT+DeepSeek 本地部署
  • 团体程序设计天梯赛-练习集——L1-041 寻找250
  • nlf 3d pose 部署学习笔记
  • (尚硅谷 Java 学习 B 站大学版)Day17 多态练习
  • 目标检测IoU阈值全解析:YOLO/DETR模型中的精度-召回率博弈与工程实践指南
  • String、StringBuffer、StringBuilder 区别
  • Spring Boot 如何实现自动配置?
  • 箭头函数的this指向谁
  • 黄晨光任中科院空间应用工程与技术中心党委书记、副主任
  • 习近平向“和平薪火 时代新章——纪念中国人民抗日战争和苏联伟大卫国战争胜利80周年中俄人文交流活动”致贺信
  • 联想发布超级智能体矩阵,杨元庆:美国关税影响反映在产品定价上,未来不确定性很大
  • 外交部:应美方请求举行贸易代表会谈,中方反对美滥施关税立场没有变化
  • 金价大反攻,国内金饰价格涨回千元,能否重返巅峰?
  • 微软通讯软件Skype正式停止运营:斥资85亿美元购入,月活用户曾超3亿