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

【LeetCode 热题 100】62. 不同路径——(解法四)组合数学

Problem: 62. 不同路径

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(min(m, n))
    • 空间复杂度:O(1)

整体思路

这段代码旨在解决 “不同路径” 问题,但它采用的是一种与动态规划完全不同的 组合数学 (Combinatorics) 方法。这种方法将问题从一个路径计数问题,抽象成了一个排列组合问题,从而可以直接通过数学公式进行计算,效率极高。

  1. 问题重构

    • 要从 m x n 网格的左上角 (0,0) 移动到右下角 (m-1, n-1),机器人必须且只能向下移动 m-1 步,向右移动 n-1 步。
    • 因此,无论走哪条路径,总的移动步数是固定的,即 (m-1) + (n-1) = m + n - 2 步。
    • 任何一条有效的路径,都可以看作是这 m + n - 2 步的一个序列,其中包含了 m-1 个“向下”和 n-1 个“向右”。
  2. 组合数学模型

    • 问题现在转化为:在一个总长度为 m + n - 2 的序列中,选择 m-1 个位置放置“向下”的移动(剩下的位置自然就是“向右”),总共有多少种不同的选择方法?
    • 这正是一个经典的组合问题,可以用组合数公式 C(n, k) 来表示,即“从 n 个不同元素中取出 k 个元素的组合数”。
    • 在这里,n = m + n - 2(总步数),k = m - 1(选择向下移动的步数)。
    • 所以,路径的总数 = C(m + n - 2, m - 1)
  3. 组合数公式的计算

    • 组合数公式为: C(n, k) = n! / (k! * (n-k)!)
    • 代入我们的变量:C(m+n-2, m-1) = (m+n-2)! / ((m-1)! * (n-1)!)
    • 直接计算阶乘可能会导致非常大的中间数,从而轻易地超出 long 类型的范围,导致溢出。
    • 因此,代码采用了一种更聪明的迭代计算方式来求解组合数。
    • C(m+n-2, m-1)可以展开为:
      [(m+n-2) * (m+n-3) * ... * (n)] / [(m-1) * (m-2) * ... * 1]
    • 代码中的循环 for (int i = 1; i <= m - 1; i++) 正是实现了这个展开式。在每次迭代中:
      • ans 乘以 (n - 1 + i),这对应了分子中的一项。
      • ans 除以 i,这对应了分母中的一项。
    • ans = ans * (n - 1 + i) / i; 这种交替进行乘法和除法的方式,可以有效地保持中间结果 ans 尽可能小,从而避免溢出。同时,由于组合数必然是整数,这里的除法也保证是整除。
  4. 数据类型

    • 使用 long 类型的 ans 变量是为了防止在计算过程中,即使交替乘除,中间结果也可能超出 int 的范围。

完整代码

class Solution {/*** 计算从 m x n 网格的左上角到右下角的不同路径数(组合数学法)。* @param m 网格的行数* @param n 网格的列数* @return 不同的路径总数*/public int uniquePaths(int m, int n) {// ans 用于存储计算结果。使用 long 类型防止中间过程溢出。// 初始化为 1,因为 1 是乘法单位元。long ans = 1;// 该循环用于计算组合数 C(m+n-2, m-1)。// 循环 m-1 次,对应组合数公式展开后的 m-1 项。for (int i = 1; i <= m - 1; i++) {// 核心计算步骤:ans = ans * (分子项) / (分母项)// 分子项从 n 开始,递增 m-1 次,即 n, n+1, ..., n+m-2//   在循环中,当 i=1, (n-1+i) = n; 当 i=m-1, (n-1+i) = n+m-2// 分母项是 (m-1)!,即 1, 2, ..., m-1//   在循环中,i 恰好遍历了 1, 2, ..., m-1ans = ans * (n - 1 + i) / i;}// 将最终的 long 类型结果强制转换为 int 并返回。// 题目的约束保证最终结果不会超出 int 范围。return (int) ans;}
}

时空复杂度

时间复杂度:O(min(m, n))

  1. 循环:算法的核心是一个 for 循环,它从 i = 1 遍历到 m-1
  2. 计算依据
    • 循环的执行次数是 m-1 次。因此,时间复杂度为 O(m)
    • 优化说明:根据组合数的性质 C(n, k) = C(n, n-k),我们可以选择计算 C(m+n-2, m-1)C(m+n-2, n-1)。为了使循环次数最少,我们应该选择 min(m-1, n-1) 作为循环的次数。因此,一个更优化的实现的时间复杂度是 O(min(m, n))
    • 尽管当前代码固定为 O(m),但其本质是线性的,并且可以轻松优化到 O(min(m, n))

空间复杂度:O(1)

  1. 主要存储开销:算法没有创建任何与输入规模 mn 成比例的新的数据结构。
  2. 辅助变量:只使用了 ansi 等几个固定数量的变量。

综合分析
算法所需的额外辅助空间是常数级别的。因此,其空间复杂度为 O(1)。这是解决此问题时空效率最高的方法。

http://www.dtcms.com/a/358264.html

相关文章:

  • 聊一聊 .NET 的 AssemblyLoadContext 可插拔程序集
  • rhel-server-7.9-x86_64-dvd.iso
  • 机器学习中KNN算法介绍
  • 笔记共享平台|基于Java+vue的读书笔记共享平台系统(源码+数据库+文档)
  • 数据库原理及应用_数据库基础_第3章数据库编程_常用系统函数
  • 骑行商城怎么开发
  • 【金仓数据库产品体验官】KingbaseES-ORACLE兼容版快速体验
  • 国家统计局数据分析01——机器学习
  • GD32VW553-IOT 基于 vscode 的 bootloader 移植(基于Cmake)
  • 【DreamCamera2】相机应用修改成横屏后常见问题解决方案
  • 阿里云营业执照OCR接口的PHP实现与技术解析:从签名机制到企业级应用
  • LZ4 解压工具(WPF / .NET 8)说明书
  • Java Stream API并行流性能优化实践指南
  • 基于Kubernetes自定义调度器的资源隔离与性能优化实践指南
  • 从 0 到 1 构建零丢失 RabbitMQ 数据同步堡垒:第三方接口数据零丢失的终极方案
  • 人工智能学习:Python相关面试题
  • 人工智能学习:Linux相关面试题
  • 98、23种设计模式之代理模式(7/23)
  • spark.sparkContext.broadcast() 与 org.apache.spark.sql.functions.broadcast 的区别
  • 开源PPT生成智能体(Agent)全景透视:技术路线、代表项目与未来趋势
  • 鸿蒙ArkTS 核心篇-15-条件渲染(组件)
  • 三重积分的性质
  • [论文阅读] 人工智能 + 软件工程 | 从“法律条文”到“Gherkin脚本”:Claude与Llama谁更懂合规开发?
  • comfUI背后的技术——VAE
  • [创业之路-581]:如何驾驭不确定性和风险,并从中获利?
  • 什么是雪花算法
  • [Mysql数据库] 知识点总结7
  • 直播间整蛊玩法
  • 【一】Django框架版本介绍
  • 2025 批量下载hasmart所有知乎回答,文章和想法,导出txt,html和pdf