代码随想录算法训练营第三十八天|62. 不同路径,63. 不同路径 II,343. 整数拆分,96. 不同的二叉搜索树

62. 不同路径,63. 不同路径 II,343. 整数拆分,96. 不同的二叉搜索树

    • 62. 不同路径
    • 63. 不同路径 II
    • 343. 整数拆分
    • 96. 不同的二叉搜索树

62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1
输入:m = 3, n = 7
输出:28

示例 2
输入:m = 3, n = 2
输出:3
解释
从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向下

示例 3
输入:m = 7, n = 3
输出:28

示例 4
输入:m = 3, n = 3
输出:6

class Solution:def uniquePaths(self, m: int, n: int) -> int:dp = [[0] * n for _ in range(m)]for i in range(m):for j in range(n):if i == 0 or j == 0:if i == 0 and j == 0:dp[i][j] = 1elif i == 0:dp[i][j] = dp[i][j - 1]else:dp[i][j] = dp[i - 1][j]else:dp[i][j] = dp[i][j - 1] + dp[i - 1][j]return dp[i][j]

直接生成dp数组,根据题目要求遍历,当某一点 [ i , j [i,j [i,j]可达的时候,必然可以到达 [ i − 1 , j ] [i-1,j] [i1,j] [ i , j − 1 ] [i,j-1] [i,j1],路径数为二者之和,代码增加对边界的判断就行。
参考代码

class Solution:def uniquePaths(self, m: int, n: int) -> int:# 创建一个二维列表用于存储唯一路径数dp = [[0] * n for _ in range(m)]# 设置第一行和第一列的基本情况for i in range(m):dp[i][0] = 1for j in range(n):dp[0][j] = 1# 计算每个单元格的唯一路径数for i in range(1, m):for j in range(1, n):dp[i][j] = dp[i - 1][j] + dp[i][j - 1]# 返回右下角单元格的唯一路径数return dp[m - 1][n - 1]

第一行和第一列可以事先声明。

class Solution:def uniquePaths(self, m: int, n: int) -> int:# 创建一个二维列表用于存储唯一路径数dp = [[0] * n for _ in range(m)]# 设置第一行和第一列的基本情况for i in range(m):dp[i][0] = 1for j in range(n):dp[0][j] = 1# 计算每个单元格的唯一路径数for i in range(1, m):for j in range(1, n):dp[i][j] = dp[i - 1][j] + dp[i][j - 1]# 返回右下角单元格的唯一路径数return dp[m - 1][n - 1]

tips:求组合的时候,要防止两个int相乘溢出! 所以不能把算式的分子都算出来,分母都算出来再做除法。

数论方法,到达 [ m , n ] [m,n] [m,n],共需要走 m + n − 2 m+n-2 m+n2步,其中向右 n − 1 n-1 n1步向下 m − 1 m-1 m1步。转化为,m + n - 2个不同的数,随便取m - 1个数,有几种取法
c m + n − 2 m − 1 c^{m-1}_{m+n-2} cm+n2m1

63. 不同路径 II

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

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

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

测试用例保证答案小于等于 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

class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:m = len(obstacleGrid)n = len(obstacleGrid[0])dp = [[0] * n for _ in range(m)]for i in range(m):for j in range(n):if obstacleGrid[i][j] == 1:dp [i][j] = 0else:if i == 0 or j == 0:if i == 0 and j == 0:dp[i][j] = 1elif i == 0:dp[i][j] = dp[i][j - 1]else:dp[i][j] = dp[i - 1][j]else:dp[i][j] = dp[i][j - 1] + dp[i - 1][j]return dp[i][j]

和上题一样,增加一个障碍物判断,遇到障碍物时候,无法到达目标所以该位置dp值是0。

343. 整数拆分

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

class Solution:def integerBreak(self, n: int) -> int:dp = [0]* (n+1)dp[1] = 1#初始化for i in range(2,n+1):#dp[n]记录n的值,所以长度是n+1res = 0for j in range(1,i):#从1到i-1分割res = max(res,j * dp[i-j],j*(i-j))dp[i] = resreturn dp[n]

维护dp数组,代表正整数n拆分后的最大乘积。

  • 假设k=2时,拆分正整数 n n n乘积达到最大值,则 j j j 2 2 2遍历到 n − 1 n-1 n1,最大值在 ( n − j ) ∗ j (n-j)*j (nj)j之间。
  • 假设k=3时,拆分正整数 n n n乘积达到最大值,从正整数拆分一个 i i i后,问题转化为 n − i n-i ni拆分2个值后最大值, d p [ n − i ] dp[n-i] dp[ni]已经维护。最大值为 i ∗ d p [ n − i ] i*dp[n-i] idp[ni],遍历 i i i返回最大值。
  • k=3,k=4以此类推

参考代码

  • 只初始化 d p [ 2 ] = 1 dp[2] = 1 dp[2]=1,从 d p [ i ] dp[i] dp[i]的定义来说,拆分数字 2 2 2,得到的最大乘积是 1 1 1, d p [ 1 ] dp[1] dp[1], d p [ 0 ] dp[0] dp[0]数值无意义,初始化只是方便计算,不好解释。
  • 拆分一个数n 使之乘积最大,那么一定是拆分成m个近似相同的子数相乘才是最大的。例如 6 拆成 3 * 3, 10 拆成 3 * 3 * 4。 100的话 也是拆成m个近似数组的子数 相乘才是最大的。只不过我们不知道m究竟是多少而已,但可以明确的是m一定大于等于2,既然m大于等于2,也就是 最差也应该是拆成两个相同的 可能是最大值。那么 j 遍历,只需要遍历到 n/2 就可以,后面就没有必要遍历了,一定不是最大值
class Solution:# 假设对正整数 i 拆分出的第一个正整数是 j(1 <= j < i),则有以下两种方案:# 1) 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j * (i-j)# 2) 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j * dp[i-j]def integerBreak(self, n):dp = [0] * (n + 1)   # 创建一个大小为n+1的数组来存储计算结果dp[2] = 1  # 初始化dp[2]为1,因为当n=2时,只有一个切割方式1+1=2,乘积为1# 从3开始计算,直到nfor i in range(3, n + 1):# 遍历所有可能的切割点for j in range(1, i // 2 + 1):# 计算切割点j和剩余部分(i-j)的乘积,并与之前的结果进行比较取较大值dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)return dp[n]  # 返回最终的计算结果

贪心算法每次拆成n个3,如果剩下是4,则保留4,然后相乘,需要数学证明,暂时不用掌握。

class Solution:def integerBreak(self, n):if n == 2:  # 当n等于2时,只有一种拆分方式:1+1=2,乘积为1return 1if n == 3:  # 当n等于3时,只有一种拆分方式:2+1=3,乘积为2return 2if n == 4:  # 当n等于4时,有两种拆分方式:2+2=4和1+1+1+1=4,乘积都为4return 4result = 1while n > 4:result *= 3  # 每次乘以3,因为3的乘积比其他数字更大n -= 3  # 每次减去3result *= n  # 将剩余的n乘以最后的结果return result

96. 不同的二叉搜索树

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1
输入:n = 3
输出:5

示例 2
输入:n = 1
输出:1

class Solution:def numTrees(self, n: int) -> int:dp =[0]*(n+1)dp[0]=1dp[1]=1for i in range(2,n+1):for j in range(1,i+1):#j树节点,小于j和大于jdp[i]+=dp[j-1] * dp[i-j]return dp[n]

n = 3 n=3 n=3为例:

  • 1做根节点,左边小于1的节点有 0 0 0个,右边大于1的节点有 2 2 2个,返回 d p [ 0 ] ∗ d p [ 2 ] dp[0]*dp[2] dp[0]dp[2]
  • 2做根节点,左边小于1的节点有 1 1 1个,右边大于1的节点有 1 1 1个,返回 d p [ 1 ] ∗ d p [ 1 ] dp[1]*dp[1] dp[1]dp[1]
  • 3做根节点,左边小于1的节点有 2 2 2个,右边大于1的节点有 0 0 0个,返回 d p [ 2 ] ∗ d p [ 0 ] dp[2]*dp[0] dp[2]dp[0]
    根节点遍历完毕,求和。

参考代码

class Solution:def numTrees(self, n: int) -> int:dp = [0] * (n + 1)  # 创建一个长度为n+1的数组,初始化为0dp[0] = 1  # 当n为0时,只有一种情况,即空树,所以dp[0] = 1for i in range(1, n + 1):  # 遍历从1到n的每个数字for j in range(1, i + 1):  # 对于每个数字i,计算以i为根节点的二叉搜索树的数量dp[i] += dp[j - 1] * dp[i - j]  # 利用动态规划的思想,累加左子树和右子树的组合数量return dp[n]  # 返回以1到n为节点的二叉搜索树的总数量

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黎巴嫩爆炸事件分析:硬件国产自主可控的意义

黎巴嫩近期发生的寻呼机爆炸事件&#xff0c;不仅对当地社会造成了冲击&#xff0c;也在全球范围内引发了对通信设备安全性的深刻反思。这一事件凸显了在全球化背景下&#xff0c;电子产品安全性的重要性&#xff0c;以及自主可控技术在保障国家安全和公共安全中的关键作用。 …

DataWhale10月动手实践——Bot应用开发task02学习笔记

一、Prompt工程 之前有接触过一些Prompt工程的内容&#xff0c;也做过一些简单的应用&#xff0c;比如使用langchain和Openai库自己搭建了一个助手项目&#xff0c;但是还从未关注过在智能体方面的Prompt。在这篇博客中&#xff0c;我会将我之前掌握的和在本次任务学习中掌握的…

【C++】在Windows中使用Boost库——实现TCP、UDP通信

目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包&#xff0c;然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台&#xff0c;在“bootstrap.…

ROS2 常用工具之Launch -- 启动管理工具

基于上一篇的action代码上继续&#xff0c;链接如上&#xff1a; ROS2 通信三大件之动作 -- Action-CSDN博客 参考链接&#xff1a;ROS2——教你写新版Launch文件 | 范子琦的博客 1、创建文件 src/action_moudle/launch/action_launch.launch.py 路径下创建文件action_lau…

腾讯六宫格本地识别,本地模型识别,腾讯六图识别

基于K哥爬虫昨天发的文章&#xff0c;特此训练了一版腾讯模型&#xff0c;效果不错&#xff0c;特此感谢K哥的指导&#xff0c;效果如下图: 有需求&#xff0c;有疑问的欢迎评论区点出

尚硅谷大数据Flink1.17实战教程-笔记04【Flink DataStream API】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷大数据Flink1.17实战教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据Flink1.17实战教程-笔记01【Flink 概述、Flink 快速上手】尚硅谷大数据Flink1.17实战教程-笔记02【Flink 部署】尚硅…

【Spring篇】初识之Spring的入门程序及控制反转与依赖注入

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】&#xff0c;【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 文章目录 &#x1f3af;初始Spring …

【K8S系列】Kubernetes pod节点NotReady问题及解决方案详解【已解决】

Kubernetes 集群中的每个节点都是运行容器化应用的基础。当节点状态显示为 NotReady 时&#xff0c;意味着该节点无法正常工作&#xff0c;这可能会导致 Pod 无法调度&#xff0c;从而影响整个应用的可用性。本文将深入分析节点不健康的各种原因、详细的排查步骤以及有效的解决…

查看SQL执行计划 explain

查看SQL执行计划 explain explain使用方式 alter session set current_schematest; explain plan for sql语句; --并不会实际执行&#xff0c;因此生成的执行计划也是预估的 select * from table(dbms_xplan.display); explain使用场景 1.内存中没有谓词信息了&#xff0…

MySQL从入门到跑路

SQL语言 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理和操作关系数据库的一种标准编程语言。 SQL分类&#xff1a; DDL(Data Definition Language)&#xff1a;数据定义语言&#xff0c;用于操作数据库、表、字段&#xff0c…

前端文件流导出

1、前端代码 ​ /** 导出 */ const handleExport async () > {let config {responseType: blob,headers: {Content-Type: application/json,},};const res await getTargetExport(config);const blob new Blob([res]);const fileName PK目标跟进导出列表.xls;const li…

SpringBoot整合Freemarker(一)

Freemarker和jsp一样是一个视图的引擎模板&#xff0c;其实所有的模板引擎的工作原理都是类似的&#xff0c;如下图&#xff1a; 接下来就具体讲解一下Freemarker的用法&#xff0c;参考手册&#xff1a;模板 数据模型 输出 - FreeMarker 中文官方参考手册 SpringBoot默认就…

【浏览器】如何正确使用Microsoft Edge

1、清理主页广告 如今的Microsoft Edge 浏览器 主页太乱了&#xff0c;各种广告推送&#xff0c;点右上角⚙️设置&#xff0c;把快速链接、网站导航、信息提要、背景等全部关闭。这样你就能得到一个超级清爽的主页。 网站导航       关闭 …

HarmonyOS NEXT和认证(在校生的大福利)

今天重点关注了一下HarmonyOS NEXT&#xff0c;也就是我们所说的纯血鸿蒙&#xff01; 根据官方的说法&#xff1a; 欢迎开发者进入HarmonyOS NEXT。暌违一年&#xff0c;HarmonyOS NEXT终于在万千开发者的期待下从幕后走向台前。 HarmonyOS NEXT采用全新升级的系统架构&#…

【Python】NumPy(一):数据类型、创建数组及基本操作

目录 ​NumPy初识 1.什么是NumPy&#xff1f; NumPy的应用 NumPy数据类型 Python基本数据类型 NumPy数据类型 NumPy数组 创建数组 1.使用numpy.array() 2.使用arange()方法创建 3.使用linspace()创建等差数列 4使用zeros()创建数组 5.使用ones()创建数组 6.利用…

Linux基本使用和程序部署

文章目录 一. Linux背景Linux发行版 二. Linux环境搭建Linux常见命令lspwdcdtouchcatmkdirrmcpmvtailvimgreppsnetstat管道 三. 搭建java部署环境安装jdk安装mysql部署Web项目到Linux 一. Linux背景 1969−1970年,⻉尔实验室的DennisRitchie和KenTompson开发了Unix操作系统. 他…

在Linux操作系统上安装NVM教程——CentOS 7/VMware 17版

目录 一、测试网络是否能上网 二、下载阿里云镜像 三、解决执行yum命令出现报错&#xff08;没有就跳过&#xff09; 四、下载NVM安装包 五、解压NVM安装包 六、安装Node 七、连接新的动态库 八、升级GLIBC版本 九、安装GCC 十、查看当前服务器CentOS版本 一、测试网…

[AWS云]kafka调用和创建

背景:因为因为公司的项目需要使用AWS的kafka&#xff0c;但是在创建和使用过程中都遇到了一些报错和麻烦&#xff0c;毕竟老外的东西&#xff0c;和阿里云、华为使用起来还是不一样。 一、创建&#xff08;创建的配置过程就略了&#xff0c;就是配置一下可用区、型号&#xff0…

闯关leetcode——110. Balanced Binary Tree

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/balanced-binary-tree/description/ 内容 Given a binary tree, determine if it is height-balanced. A height-balanced binary tree is a binary tree in which the depth of the two subtrees…

深入理解售后派单管理系统,功能优势一览

售后派单管理系统优化售后服务流程&#xff0c;提升响应速度、运营效率和服务质量。ZohoDesk等系统通过自动化派单、实时调度监控等功能&#xff0c;助力企业赢得竞争优势。适用于电子产品、汽车、IT及房地产等行业。 一、什么是售后派单管理系统 售后派单管理系统是一种专门用…