【算法与数据结构】62、LeetCode不同路径

news2024/11/17 0:53:39

文章目录

  • 一、题目
  • 二、解法
    • 2.1 动态规划解法
    • 2.2 数论解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述

二、解法

2.1 动态规划解法

  思路分析:机器人只能向下或者向右移动,那么到达(i,j)位置的路径和(i-1,j)以及(i,j-1)有关。那么我们就得到的动态规划的表达式 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][j]=dp[i-1][j]+dp[i][j-1] dp[i][j]=dp[i1][j]+dp[i][j1]。其中,因为到达第一行和第一列位置的路径只有一条,因此dp数组中第一行第一列的元素都为1。根据如上信息,我们写出如下代码。
  程序如下

class Solution {
public:
	int uniquePaths(int m, int n) {
		vector<vector<int>> dp(m, vector<int>(n, 1));
		for (int i = 1; i < m; i++) {
			for (int j = 1; j < n; j++) {
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			}
		}
		return dp[m - 1][n - 1];
	}
};

复杂度分析:

  • 时间复杂度: O ( m ∗ n ) O(m*n) O(mn)
  • 空间复杂度: O ( m ∗ n ) O(m*n) O(mn)

  上述代码还可以再空间上进行压缩。从二维数组的角度来看,(i,j)位置的路径数等于它上方的元素和左边的元素之和。如果省略掉上方的元素,我们就能用一个一维数组来表示dp数组。迭代公式为 d p [ i ] = d p [ i ] + d o p [ i − 1 ] dp[i] = dp[i]+dop[i-1] dp[i]=dp[i]+dop[i1],其中dop[i-1]代表左边元素,公式右边旧的dp[i]代表上方元素。最终输出为dp[n-1]。

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int> dp(n);
        for (int i = 0; i < n; i++) dp[i] = 1;
        for (int j = 1; j < m; j++) {
            for (int i = 1; i < n; i++) {
                dp[i] += dp[i - 1];
            }
        }
        return dp[n - 1];
    }
};

复杂度分析:

  • 时间复杂度: O ( m ∗ n ) O(m*n) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)

2.2 数论解法

  思路分析:从数学上我们可以知道,要到达终点,每次又只能走一步,那么总共需要的步数是 m + n − 2 m+n-2 m+n2,那么有 m − 1 m-1 m1步是要往下走的,那么问题就变成了在 m + n − 2 m+n-2 m+n2步中, m − 1 m-1 m1步往下走有多少种组合。这是一个组合问题。因此,问题变成计算 C m + n − 2 m − 1 = ( m + n − 2 ) ! ( m − 1 ) ! ( n − 1 ) ! = ( m + n − 2 ) ∗ . . . ( n + 1 ) ∗ n ( m − 1 ) ! C_{m+n-2}^{m-1}=\frac{(m+n-2)!}{{(m-1)!}{(n-1)!}}=\frac{(m+n-2)*...(n+1)*n}{(m-1)!} Cm+n2m1=(m1)!(n1)!(m+n2)!=(m1)!(m+n2)...(n+1)n。结合上述讨论,我们写出如下代码。代码当中,为了防止乘积中分子溢出,我们首先使用long long类型,并在循环中不断除以分母。
  程序如下

class Solution {
public:
	int uniquePaths(int m, int n) {
		long long numerator = 1; // 分子
		int denominator = m - 1; // 分母
		int num1 = m - 1, num2 = m + n - 2;
		while (num1--) {
			numerator *= (num2--);
			while (denominator != 0 && numerator % denominator == 0) {	// 分母不能为0, 且分子要能整除分母
				numerator /= denominator;
				denominator--;
			}
		}
		return numerator;
	}
};

复杂度分析:

  • 时间复杂度: O ( m ) O(m) O(m)
  • 空间复杂度: O ( 1 ) O(1) O(1)

三、完整代码

# include <iostream>
# include <vector>
using namespace std;

// 62、不同路径I
class Solution {
public:
	int uniquePaths(int m, int n) {
		vector<vector<int>> dp(m, vector<int>(n, 1));
		for (int i = 1; i < m; i++) {
			for (int j = 1; j < n; j++) {
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			}
		}
		return dp[m - 1][n - 1];
	}
};

// 滚动数组削减空间复杂度
//class Solution {
//public:
//	int uniquePaths(int m, int n) {
//		vector<int> dp(n);
//		for (int i = 0; i < n; i++) dp[i] = 1;
//		for (int j = 1; j < m; j++) {
//			for (int i = 1; i < n; i++) {
//				dp[i] += dp[i - 1];
//			}
//		}
//		return dp[n - 1];
//	}
//};

// 数论方法
//class Solution {
//public:
//	int uniquePaths(int m, int n) {
//		long long numerator = 1; // 分子
//		int denominator = m - 1; // 分母
//		int num1 = m - 1, num2 = m + n - 2;
//		while (num1--) {
//			numerator *= (num2--);
//			while (denominator != 0 && numerator % denominator == 0) {	// 分母不能为0, 且分子要能整除分母
//				numerator /= denominator;
//				denominator--;
//			}
//		}
//		return numerator;
//	}
//};

int main() {
	int m = 3, n = 2;
	Solution s1;
	int result = s1.uniquePaths(m, n);
	cout << result << endl;
	system("pause");
	return 0;
}

end

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【金猿人物展】DataPipelineCEO陈诚:赋能数据应用,发挥未来生产力

‍ 陈诚 本文由DataPipelineCEO陈诚撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度趋势人物榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 我们处在一个“见证奇迹”的时代。在过去的20年间&#xff0c;我们见证了大数据技术快速发展所带…

Linux中Docker数据管理的数据卷及挂载

目录 一、数据管理 1. 讲述 2. 应用场景 二、数据卷的应用 1. 命令 2. tomcat镜像 3. 挂载数据卷 4. 项目部署在数据卷 三、目录挂载 四、完善Tomcat配置 每篇一获 一、数据管理 1. 讲述 Docker 的数据管理主要涉及到两个方面&#xff1a;数据卷&#xff08;Volumes&#xff09…

AVL树(Java)

目录 一、什么是AVL树 二、AVL树的实现 AVL树的节点 AVL树的插入 AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 AVL树的验证 三、AVL树的性能分析 一、什么是AVL树 在了解什么是AVL树之前&#xff0c;我们先回顾二叉搜索树的概念 二叉搜索树&#xff08;二叉排序…

使用递归将list转换成tree

在产品研发时遇到这样一个问题&#xff0c;对于省市区县这类三级联动的数据&#xff0c;前端插件需要一次把数据全部返回&#xff0c;单纯的使用接口查询字节的没办法满足要求。 如果一次把数据全部返回&#xff0c;前端使用起来很麻烦需要一条一条的进行查找。 常规的使用方…

基于SPI的插件式开发实现方案之@AutoService+ServiceLoader介绍及Dolphinscheduler中的实际应用

1.插件化开发概述 插件化开发模式正在很多编程语言或技术框架中得以广泛的应用实践&#xff0c;比如大家熟悉的jenkins&#xff0c;docker可视化管理平台rancher&#xff0c;以及日常编码使用的编辑器idea&#xff0c;vscode等。 实现服务模块之间解耦的方式有很多&#xff0…

【漏洞复现】Apache Tomcat AJP文件包含漏洞(CVE-2020-1938)

Nx01 产品简介 Apache Tomcat 是一个免费的开源 Web 应用服务器&#xff0c;在中小型企业和个人开发用户中有着广泛的应用。 Nx02 漏洞描述 默认情况下&#xff0c;Apache Tomcat会开启AJP连接器&#xff0c;由于AJP服务&#xff08;8009端口&#xff09;存在文件包含缺陷&…

Spring Boot - Application Events 的发布顺序_AvailabilityChangeEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子管理实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

数据仓库研发规范

数据仓库研发规范 本文将介绍数据仓库研发规范的阶段规划、角色职责和整体流程。 在大数据时代&#xff0c;规范地进行数据资产管理已成为推动互联网、大数据、人工智能和实体经济深度融合的必要条件。贴近业务属性、兼顾研发各阶段要点的研发规范&#xff0c;可以切实提高研…

Handsfree_ros_imu:ROS机器人IMU模块的get_imu_rpy.py文件学习记录

上一篇博客写了关于Handsfree_ros_imu&#xff1a;ROS机器人IMU模块ARHS姿态传感器&#xff08;A9&#xff09;Liunx系统Ubuntu20.04学习启动和运行教程&#xff1a; https://blog.csdn.net/qq_54900679/article/details/135539176?spm1001.2014.3001.5502 这次带来get_imu_r…

解决虚拟机的网络图标不见之问题

在WIN11中&#xff0c;启动虚拟机后&#xff0c;发现网络图标不见了&#xff0c;见下图&#xff1a; 1、打开虚拟机终端 输入“sudo server network-manager stop”&#xff0c;停止网络管理器 输入“cd /回车” &#xff0c; 切换到根目录 输入“cd var回车” &#xff0c;…

从零开始怎么做好产品宣传册

​随着市场竞争的日益激烈&#xff0c;产品宣传册作为企业与消费者之间的桥梁&#xff0c;其重要性日益凸显。一份优秀的宣传册不仅能提升企业的品牌形象&#xff0c;还能帮助企业更好地推广产品&#xff0c;吸引潜在客户。然而&#xff0c;很多企业在制作宣传册时却常常无从下…

webpack原理和逆向实战

文章目录 什么是webpackwebpack基本原理webpack代码分析webpack代码抠取webpack全模块自吐webpack自动扣取总结 什么是webpack webpack是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)&#xff0c;负责分析翻译压缩打包代码。 上面的官网的一张示例图。 web…

了解及掌握二维数组

第一题: 题目&#xff08;单对角线和&#xff09;&#xff1a; 分析&#xff1a; 用结构体的话&#xff0c;太麻烦了&#xff0c;专业一点&#xff0c;用本该属于它的知识点来解决它。 代码&#xff1a; #include <iostream> using namespace std; int main() { int…

设计模式—行为型模式之状态模式

设计模式—行为型模式之状态模式 状态&#xff08;State&#xff09;模式&#xff1a;对有状态的对象&#xff0c;把复杂的“判断逻辑”提取到不同的状态对象中&#xff0c;允许状态对象在其内部状态发生改变时改变其行为。 状态模式包含以下主要角色&#xff1a; 环境类&am…

如何使用iPad通过Code App+cpolar实现公网地址远程访问vscode

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. …

基于多智能体点对点转换的分布式模型预测控制

matlab2020正常运行 基于多智能体点对点转换的分布式模型预测控制资源-CSDN文库

资源三角形

美国哈佛大学的研究小组提出了著名的资源三角形&#xff1a;没有物质&#xff0c;什么也不存在&#xff1b;没有能量&#xff0c;什么也不会发生&#xff1b;没有信息&#xff0c;任何事物都没有意义。物质、能量和信息是相互有区别的&#xff0c;是人类社会赖以生存、发展的三…

7 - MySQL主从同步|主从同步模式

MySQL主从同步&#xff5c;主从同步模式 MySQL主从同步主从同步介绍主从同步工作过程主从同步结构模式配置主从同步一主一从同步结构一主多从同步结构主从从同步结构主主同步结构 主从同步模式主从同步结构模式复制模式 MySQL主从同步 主从同步介绍 存储数据的服务结构 主服务…

数据结构与算法教程,数据结构C语言版教程!(第三部分、栈(Stack)和队列(Queue)详解)五

第三部分、栈(Stack)和队列(Queue)详解 栈和队列&#xff0c;严格意义上来说&#xff0c;也属于线性表&#xff0c;因为它们也都用于存储逻辑关系为 "一对一" 的数据&#xff0c;但由于它们比较特殊&#xff0c;因此将其单独作为一章&#xff0c;做重点讲解。 使用栈…