力扣第 62 题(Unique Paths)两种递归实现

直接递归的效率会非常低,因为会重复计算许多子问题。这种方法可以结合记忆化搜索(递归 + 缓存)优化效率,使其在合理的时间内求解问题。


递归解法

1. 基本递归(不推荐)

直接递归的思路是,从起点到终点有两种选择:向下或向右。总路径数等于向下和向右的路径数之和:

  • 如果从位置 ( i , j ) (i, j) (i,j) 出发:

    f ( i , j ) = f ( i + 1 , j ) + f ( i , j + 1 ) f(i, j) = f(i+1, j) + f(i, j+1) f(i,j)=f(i+1,j)+f(i,j+1)

递归终止条件:

  • 如果机器人超出边界,返回 0。
  • 如果到达右下角,返回 1。
int uniquePathsRecursive(int m, int n) {
    if (m == 1 || n == 1) {
        return 1; // 到达边界,只有一条路径
    }
    return uniquePathsRecursive(m - 1, n) + uniquePathsRecursive(m, n - 1);
}

问题

  • 时间复杂度: O ( 2 m + n ) O(2^{m+n}) O(2m+n),因为递归会重复计算大量相同的子问题,效率非常低。

2. 记忆化搜索(递归 + 缓存)

为了解决重复计算的问题,可以使用一个二维数组缓存已经计算过的结果。

思路:
  • 创建一个二维数组 memo[m][n],用来存储从 ( i , j ) (i, j) (i,j) 出发到右下角的路径数。
  • 如果 memo[i][j] 已经计算过,直接返回。
  • 否则按照递归公式计算,并将结果存储到 memo[i][j] 中。
实现代码:
#include <stdio.h>
#include <stdlib.h>

// 递归辅助函数
int dfs(int m, int n, int i, int j, int** memo) {
    // 如果超出边界,返回 0
    if (i >= m || j >= n) {
        return 0;
    }
    // 如果到达终点,返回 1
    if (i == m - 1 && j == n - 1) {
        return 1;
    }
    // 如果已经计算过,直接返回缓存的结果
    if (memo[i][j] != -1) {
        return memo[i][j];
    }
    // 递归计算路径数,并存入缓存
    memo[i][j] = dfs(m, n, i + 1, j, memo) + dfs(m, n, i, j + 1, memo);
    return memo[i][j];
}

// 主函数
int uniquePaths(int m, int n) {
    // 创建缓存数组并初始化为 -1
    int** memo = (int**)malloc(m * sizeof(int*));
    for (int i = 0; i < m; i++) {
        memo[i] = (int*)malloc(n * sizeof(int));
        for (int j = 0; j < n; j++) {
            memo[i][j] = -1;
        }
    }

    // 调用递归函数
    int result = dfs(m, n, 0, 0, memo);

    // 释放内存
    for (int i = 0; i < m; i++) {
        free(memo[i]);
    }
    free(memo);

    return result;
}

int main() {
    int m = 3, n = 7;
    printf("不同路径的数量: %d\n", uniquePaths(m, n));
    return 0;
}

复杂度分析

时间复杂度
  • 在记忆化搜索中,每个状态 ( i , j ) (i, j) (i,j) 最多计算一次,因此总的时间复杂度为 O ( m × n ) O(m \times n) O(m×n)
空间复杂度
  • 递归栈空间复杂度为 O ( m + n ) O(m + n) O(m+n)(递归深度)。
  • 记忆化数组的空间复杂度为 O ( m × n ) O(m \times n) O(m×n)

总结

  • 小规模问题:可以使用递归解法,简单直观。
  • 中等规模问题:使用记忆化搜索或动态规划,效率高且容易实现。
  • 大规模问题:推荐组合数学解法,效率最高,但适用范围有限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/922752.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】【线性表】栈的基本概念(附c语言源码)

栈的基本概念 讲基本概念还是回到数据结构的三要素&#xff1a;逻辑结构&#xff0c;物理结构和数据运算。 从逻辑结构来讲&#xff0c;栈的各个数据元素之间是通过是一对一的线性连接&#xff0c;因此栈也是属于线性表的一种从物理结构来说&#xff0c;栈可以是顺序存储和顺…

OpenOCD之J-Link下载

1.下载USB Dirver Tool.exe&#xff0c;选择J-Link dirver&#xff0c;替换成WinUSB驱动。&#xff08;⭐USB Dirver Tool工具可将J-Link从WinUSB驱动恢复为默认驱动⭐&#xff09; 下载方式 ①官方网址&#xff1a;https://visualgdb.com/UsbDriverTool/ ②笔者的CSDN链接&…

【JavaEE初阶 — 多线程】定时器的应用及模拟实现

目录 1. 标准库中的定时器 1.1 Timer 的定义 1.2 Timer 的原理 1.3 Timer 的使用 1.4 Timer 的弊端 1.5 ScheduledExecutorService 2. 模拟实现定时器 2.1 实现定时器的步骤 2.1.1 定义类描述任务 定义类描述任务 第一种定义方法 …

ssm168基于jsp的实验室考勤管理系统网页的设计与实现+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;实验室考勤管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本实验室考勤管…

原生微信小程序在顶部胶囊左侧水平设置自定义导航兼容各种手机模型

无论是在什么手机机型下&#xff0c;自定义的导航都和右侧的胶囊水平一条线上。如图下 以上图iphone12&#xff0c;13PRo 以上图是没有带黑色扇帘的机型 以下是调试器看的wxml的代码展示 注意&#xff1a;红色阔里的是自定义导航&#xff08;或者其他的logo啊&#xff0c;返回之…

Python 获取微博用户信息及作品(完整版)

在当今的社交媒体时代&#xff0c;微博作为一个热门的社交平台&#xff0c;蕴含着海量的用户信息和丰富多样的内容。今天&#xff0c;我将带大家深入了解一段 Python 代码&#xff0c;它能够帮助我们获取微博用户的基本信息以及下载其微博中的相关素材&#xff0c;比如图片等。…

springcloud alibaba之shcedulerx实现分布式锁

文章目录 1、shcedulerx简介2、基于mysq分布式锁实现3、注解方式使用分布式锁4、编码方式使用分布式锁 1、shcedulerx简介 springcloud alibaba shcedulerx看起来有点像xxl job那样的任务调度中间件&#xff0c;其实它是一个分布式锁框架&#xff0c;含有两种实现一种基于DB实…

【LLM训练系列02】如何找到一个大模型Lora的target_modules

方法1&#xff1a;观察attention中的线性层 import numpy as np import pandas as pd from peft import PeftModel import torch import torch.nn.functional as F from torch import Tensor from transformers import AutoTokenizer, AutoModel, BitsAndBytesConfig from typ…

Selenium的八种定位方式

1. 通过 ID 定位 ID 是最直接和高效的方式来定位元素&#xff0c;因为每个页面中的 ID 应该是唯一的。 from selenium import webdriverdriver webdriver.Chrome(executable_pathpath/to/chromedriver) driver.get(https://example.com)# 通过 ID 定位 element driver.find…

MySQL底层概述—1.InnoDB内存结构

大纲 1.InnoDB引擎架构 2.Buffer Pool 3.Page管理机制之Page页分类 4.Page管理机制之Page页管理 5.Change Buffer 6.Log Buffer 1.InnoDB引擎架构 (1)InnoDB引擎架构图 (2)InnoDB内存结构 (1)InnoDB引擎架构图 下面是InnoDB引擎架构图&#xff0c;主要分为内存结构和磁…

丹摩|丹摩智算平台深度评测

1. 丹摩智算平台介绍 随着人工智能和大数据技术的快速发展&#xff0c;越来越多的智能计算平台涌现&#xff0c;为科研工作者和开发者提供高性能计算资源。丹摩智算平台作为其中的一员&#xff0c;定位于智能计算服务的提供者&#xff0c;支持从数据处理到模型训练的全流程操作…

基于企业微信客户端设计一个文件下载与预览系统

在企业内部沟通与协作中&#xff0c;文件分享和管理是不可或缺的一部分。企业微信&#xff08;WeCom&#xff09;作为一款广泛应用于企业的沟通工具&#xff0c;提供了丰富的API接口和功能&#xff0c;帮助企业进行高效的团队协作。然而&#xff0c;随着文件交换和协作的日益增…

LLM的原理理解6-10:6、前馈步骤7、使用向量运算进行前馈网络的推理8、注意力层和前馈层有不同的功能9、语言模型的训练方式10、GPT-3的惊人性能

目录 LLM的原理理解6-10: 6、前馈步骤 7、使用向量运算进行前馈网络的推理 8、注意力层和前馈层有不同的功能 注意力:特征提取 前馈层:数据库 9、语言模型的训练方式 10、GPT-3的惊人性能 一个原因是规模 大模型GPT-1。它使用了768维的词向量,共有12层,总共有1.…

大模型系列11-ray

大模型系列11-ray PlasmaPlasmaStore启动监听处理请求 ProcessMessagePlasmaCreateRequest请求PlasmaCreateRetryRequest请求PlasmaGetRequest请求PlasmaReleaseRequestPlasmaDeleteRequestPlasmaSealRequest ObjectLifecycleManagerGetObjectSealObject ObjectStoreRunnerPlas…

开源动态表单form-create-designer 扩展个性化配置的最佳实践教程

在开源低代码表单设计器 form-create-designer 的右侧配置面板里&#xff0c;field 映射规则为开发者提供了强大的工具去自定义和增强组件及表单配置的显示方式。通过这些规则&#xff0c;你可以简单而高效地调整配置项的展示&#xff0c;提升用户体验。 源码地址: Github | G…

美创科技入选2024数字政府解决方案提供商TOP100!

11月19日&#xff0c;国内专业咨询机构DBC德本咨询发布“2024数字政府解决方案提供商TOP100”榜单。美创科技凭借在政府数据安全领域多年的项目经验、技术优势与创新能力&#xff0c;入选收录。 作为专业数据安全产品与服务提供商&#xff0c;美创科技一直致力于为政府、金融、…

地平线 bev_cft_efficientnetb3 参考算法-v1.2.1

01 概述 在自动驾驶感知算法中 BEV 感知成为热点话题&#xff0c;BEV 感知可以弥补 2D 感知的缺陷构建 3D “世界”&#xff0c;更有利于下游任务和特征融合。 地平线集成了基于 bev 的纯视觉算法&#xff0c;目前已支持 ipm-based 、lss-based、 transformer-based&#xff…

C#里怎么样检测文件的属性?

C#里怎么样检测文件的属性? 对于文件来说,在C#里有一种快速的方法来检查文件的属性。 比如文件是否已经压缩, 文件是否加密, 文件是否是目录等等。 属性有下面这么多: 例子演示如下: /** C# Program to View the Information of the File*/ using System; using Syste…

最新‌VSCode保姆级安装教程(附安装包)

文章目录 一、VSCode介绍 二、VSCode下载 下载链接&#xff1a;https://pan.quark.cn/s/19a303ff81fc 三、VSCode安装 1.解压安装文件&#xff1a;双击打开并安装VSCode 2.勾选我同意协议&#xff1a;然后点击下一步 3.选择目标位置&#xff1a;点击浏览 4.选择D盘安装…

传输控制协议(TCP)和用户数据报协议(UDP)

一、传输控制协议&#xff08;TCP&#xff09; 传输控制协议&#xff08;Transmission Control Protocol&#xff0c;TCP&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由 IETF 的 RFC 793 定义。 它通过三次握手建立连接&#xff0c;确保数…