java数据结构与算法刷题-----LeetCode343. 整数拆分(TODO)

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

很多人觉得动态规划很难,但它就是固定套路而已。其实动态规划只不过是将多余的步骤,提前放到dp数组中(就是一个数组,只不过大家都叫它dp),达到空间换时间的效果。它仅仅只是一种优化思路,因此它目前的境地和线性代数一样----虚假的难。

  1. 想想线性代数,在国外留学的学生大多数不觉得线性代数难理解。但是中国的学生学习线性代数时,完全摸不着头脑,一上来就是行列式和矩阵,根本不知道这玩意是干嘛的。
  2. 线性代数从根本上是在空间上研究向量,抽象上研究线性关系的学科。人家国外的教科书都是第一讲就帮助大家理解研究向量和线性关系。
  3. 反观国内的教材,直接把行列式搞到第一章。搞的国内的学生在学习线性代数的时候,只会觉得一知半解,觉得麻烦,完全不知道这玩意学来干什么。当苦尽甘来终于理解线性代数时干什么的时候,发现人家国外的教材第一节就把这玩意讲清楚了。你只会大骂我们国内这些教材,什么狗东西(以上是自己学完线性代数后的吐槽,我们同学无一例外都这么觉得)。

而我想告诉你,动态规划和线性代数一样,我学完了才知道,它不过就是研究空间换时间,提前将固定的重复操作规划到dp数组中,而不用暴力求解,从而让效率极大提升。

  1. 但是网上教动态规划的兄弟们,你直接给一个动态方程是怎么回事?和线性代数,一上来就教行列式和矩阵一样,纯属恶心人。我差不多做了30多道动态规划题目,才理解,动态方程只是一个步骤而已,而这已经浪费我很长时间了,我每道题都一知半解不理解,过程及其痛苦。最后只能重新做。
  2. 动态规划,一定是优先考虑重复操作与dp数组之间的关系,搞清楚后,再提出动态方程。而你们前面步骤省略了不讲,一上来给个方程,不是纯属扯淡吗?
  3. 我推荐研究动态规划题目,按5个步骤,从上到下依次来分析
  1. DP数组及下标含义
  2. 递推公式
  3. dp数组初始化
  4. 数组遍历顺序(双重循环及以上时,才考虑)
  5. dp数组打印,分析思路是否正确(相当于做完题,检查一下)

在这里插入图片描述

方法一:时间复杂度O( n 2 n^2 n2),空间复杂度O(n)

先理解题目细节

在这里插入图片描述
在这里插入图片描述

  1. 这种解法的思路,就是用dp数组保存小于等于目标值n的,每一个正整数值i,将i依次看做要拆分的数,找出它们每一个的最大乘积情况。最终递推到目标值n.
  2. 上面解析过程中,频繁出现i = j+(i-j) 和 i = j+dp[i-j]。这个初学者会很难理解。
  1. i是我们当前要拆分的数,j是我们这次拆分必须有的数,比如i=10代表我们要拆分10这个数,试图找到它的最大乘积。而我们先从j=1开始枚举,也就是这次拆分,必须拆出一个1,剩下的你随便。再比如j=3时,就是我们这次必须先拆出来一个3,剩下的7你随便怎么拆。
  2. 而如果我们只想拆成2个数,比如10 = 1 + 9. i = 10. 而j = 1就表示我们这次拆出来的两个数里面,其中一个必须是1. 剩下一个数是多少呢?不就是10-1 ==> i-j = 9吗。这就有了10 = 1+(10-1) ==> i = j+(i-j)
  3. 那如果我们想拆成3和数或者更多呢?比如我们i = 10. j = 1,也就是这次必须拆出一个1. 那么剩下的9 我们随便怎么拆都行。拆成5和4,或者2和7,满足条件就行.
  4. 但是题目要求我们要最大情况。也就是说剩下的9,我们必须拆成最大的情况。
  5. 那么dp[9]表示的是什么呢?不就是将9拆分,然后乘起来后的最大情况吗?那么既然i = 10,j = 1,剩下的9我们又要拆分成最大情况。那么直接取dp[10-1] 不就可以了吗。 也就有了i = j+dp[i-j];
  1. 因此,这个解法的关键就是,算出从正整数1~n的每个数拆分后乘积的最大情况,保存到dp[i]中。
  1. 如何拆分:枚举每一种情况,用j表示这次拆分,必须拆出来的一个数。j从1开始一直枚举。显然这里是个可以优化的点。方法二会指出。
  2. 每种情况拆分后:算出乘积后,保留最大值,因为题目要求保留最大情况。
解题思路
  1. 暴力求解的思想,就是从1到n一直尝试每一种值,每一种情况。
  2. 但是如果我们预先将其存储到dp数组,就可以直接通过dp, 获取数据,而不用枚举。典型的动态规划题目
  1. 暴力求解,需要每次对两个东西枚举,这种解法只需对一个东西枚举。第二种方法,不需要枚举。
动态规划思考5步曲
  1. DP数组及下标含义
  1. 我们要求出的是当前数拆分后的数乘起来的最大情况。显然dp数组中存储的就是当前数拆分后的数乘起来的最大情况。要求出谁的?显然是对哪个数拆分。那么下标就是代表对哪个数拆分,很显然,只需要一个下标,也就是一维数组。
  1. 递推公式
  1. 因为一个数最少拆成两个数,所以0和1没法拆成两个正整数,正整数从1开始。故:F(0) = F(1) = 0;
  2. 对于其它数i,都有两种情况,将当前数拆分成两个数,设其中一个数为j,则另一个数是i-j,也就是F(i) = j+(i-j)
  3. 另一种情况就是拆成3个及以上个数。设其中一个为j,则剩下的数是i - j = x。这个x拆分后乘积最大情况,我们已经规划过了,就是F(x). 故:F(i) = j+F(i-j)
  1. dp数组初始化

在这里插入图片描述

  1. 数组遍历顺序(单重循环,无需考虑遍历顺序,一共就一维,哪里来的谁先谁后)
  2. 打印dp数组(自己生成dp数组后,将dp数组输出看看,是否和自己预想的一样。)

在这里插入图片描述

代码:时间复杂度O(n^2).空间复杂度O(n)

在这里插入图片描述

class Solution {public int integerBreak(int n) {int dp[] = new int[n+1];//从0到n,共n+1个值for(int i = 2; i <= n ; i++){//至少拆成两个数,从2开始int curMax = 0;//用于保存从拆出一个1开始,每种枚举情况的最大值for(int j = 1;j<i;j++) {//比较curMax当前枚举最大情况,和现在正在枚举的情况,谁大。保留大的curMax = Math.max(curMax,Math.max(j*(i-j),j*dp[i-j]));//当前值有两种拆分方案,拆成两个数,或者多个数}dp[i] = curMax;//只考虑最大情况}return dp[n];//我们只需要n的拆分后乘积最大情况}
}

方法一优化:时间复杂度O(n* l o g 2 n log_2{n} log2n)空间复杂度O(n)

我们每次拆分发现,最大情况下,拆出来的值,都相似,相差不多。而且它们都没有超过一半。比如n = 10 拆出的最大情况是4,3,3. 完全超不过它的一半,也就是超不过5
因此,我们枚举j的时候,只需枚举i/2次
在这里插入图片描述

class Solution {public int integerBreak(int n) {int dp[] = new int[n+1];//从0到n,共n+1个值for(int i = 2; i <= n ; i++){//至少拆成两个数,从2开始int curMax = 0;//用于保存从拆出一个1开始,每种枚举情况的最大值for(int j = 1;j<=i/2;j++) {//根据数学规律,每个数拆分后想要乘积最大情况下。j不可能超过i的一半//比较curMax当前枚举最大情况,和现在正在枚举的情况,谁大。保留大的curMax = Math.max(curMax,Math.max(j*(i-j),j*dp[i-j]));//当前值有两种拆分方案,拆成两个数,或者多个数}dp[i] = curMax;//只考虑最大情况}return dp[n];//我们只需要n的拆分后乘积最大情况}
}

方法二:时间复杂度O(n),空间复杂度O(n)

通过数学归纳我们发现,例如10 = 3+4+3,拆分出的数字一个是它们都不会超过10的一半5.另一个它们都与10的一半5,相差2或者3. 也就是必然拆出2和3中的一个。这是大学数学相关课程的内容。如果你还对高数有印象,应该记得函数的极值如何求吧,但这是方法三会用到的。我们这里只是用了数学归纳法。

  1. 同样我们发现,2和3很固定,拆分2后结果为1,拆分3后结果为2.都是自己本身-1,也就是n-1. 所以如果题目要求我们拆分的n = 2或者3,直接返回n-1即可。

在这里插入图片描述

class Solution {public int integerBreak(int n) {if (n <= 3) {//n给的<=3直接返回n-1.这是它的数学规律return n - 1;}int[] dp = new int[n + 1];dp[2] = 1;for (int i = 3; i <= n; i++) {//根据规律,拆出的数,最大情况下,都包含3或者2的一个。dp[i] = Math.max(Math.max(2 * (i - 2), 2 * dp[i - 2]), Math.max(3 * (i - 3), 3 * dp[i - 3]));}return dp[n];}
}

方法三:时间复杂度O(1),空间复杂度O(1)

导师让我今天这篇文章必须发出来,他晚上给编程小组讲课要用,但是这个方法,我还没想好怎么讲清楚,反正他们参加比赛也用不到这种难度的方法,所以日后补充。

写了两版稿子,依然不知道如何能讲解的通俗易懂,比如下面的驻点,我试图解释清楚,但涉及到了导数的定义和证明,我需要一定时间思考,如何让没学过微积分的人也能看懂。所以下面我先给出用数学做这道题的所需公式和最终代码。学过微积分的都可以很轻松做出来,因为这严格意义来说,难度只是一道高考的导数压轴题,放到考研数学里面,可能放到选择题第一题都让人觉得是送分题。会的人可以直接参考一下,日后我会补充。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {public int integerBreak(int n) {if(n <= 3) return n - 1;int a = n / 3, b = n % 3;if(b == 0) return (int)Math.pow(3, a);if(b == 1) return (int)Math.pow(3, a - 1) * 4;return (int)Math.pow(3, a) * 2;}
}

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

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

相关文章

jenkins构建git项目timeout

问题点&#xff1a; Started by user unknown or anonymous Running as SYSTEM Building in workspace /var/jenkins_home/workspace/test-one using credential f28d956-8ee1-4f20-a32b-06879b487c70 Cloning the remote Git repository Cloning repository http://git.cc.co…

Flink CDC使用

Flink 环境准备 Flink 版本对应的CDC版本 两个jar包上传到flink bin目录下 flink-sql-connector-mysql-cdc mysql-connector-java 重启Flink集群

stm32的FMC数据访问与突发模式

数据访问 配置外部存储器的宽度为 16 位&#xff0c; FMC 将使用内部的 ADDR[25:1]地址来作为对外部存储器的寻址地址 FMC_A[24:0]&#xff0c;这段描述是在解释在STM32的FMC&#xff08;Flexible Memory Controller&#xff09;中&#xff0c;如何配置外部存储器的宽度为16位…

资产信息管理系统-前后端开发

题目要求&#xff1a; 资产管理系统 利用H5规范&#xff0c;CSS样式与JS脚本独立于HTML页面&#xff0c;Javascript调用jQuery库&#xff0c;CRUD后端使用FastAPI封装&#xff0c;前端页面在Nginx中运行&#xff0c;调用API模块&#xff0c; 实现CURD的课设总结 基本设计&am…

【已解决】c语言编写的lib如何调用

本博文源于笔者在vs2015正在编写的lib想要调用的问题&#xff0c;正常的操作是将项目生成lib&#xff0c;但是然后又如何操作呢&#xff0c;本博文就是解决这样的问题 文章目录 问题再现步骤1&#xff1a;编写lib.h与lib.c步骤2&#xff1a;生成lib步骤3&#xff1a;添加用得到…

7 集中式日志和分布式跟踪

文章目录 日志聚合模式日志集中化的简单解决方案使用日志并输出分布式跟踪Spring Cloud Sleuth实现分布式跟踪 小结 前面的文章&#xff1a; 1、 1 一个测试驱动的Spring Boot应用程序开发 2、 2 使用React构造前端应用 3、 3 试驱动的Spring Boot应用程序开发数据层示例 4、…

中国京津冀国际光伏展

中国京津冀国际光伏展是一个专门展示光伏技术和产品的展览会。该展览会旨在促进光伏产业的发展和推广&#xff0c;推动太阳能光伏的应用和利用。 这个展览会通常会邀请国内外的光伏企业和专家参加&#xff0c;展示最新的光伏技术和产品&#xff0c;包括太阳能电池板、光伏组件、…

RequestMapping注解的使用和常见的GET和POST请求方式

RequestMapping注解的使用和常见的GET和POST请求方式 1、使用说明 作用&#xff1a;用于建立请求URL和处理请求方法之间的对应关系。 出现位置&#xff1a; 类上&#xff1a; 请求 URL的第一级访问目录。此处不写的话&#xff0c;就相当于应用的根目录。写的话需要以/开头。它…

计算机科学速成课【学习笔记】(4)——二进制

本集课程B站链接&#xff1a; 4. 二进制-Representing Numbers and Letters with Binary_BiliBili_哔哩哔哩_bilibili4. 二进制-Representing Numbers and Letters with Binary_BiliBili是【计算机科学速成课】[40集全/精校] - Crash Course Computer Science的第4集视频&…

Vue生命周期图解

生命周期四个阶段&#xff1a; ① 创建 ② 挂载 ③ 更新 ④ 销毁 图解&#xff1a; 包含8个钩子函数

C# 日期转换“陷阱”

在 C# 中&#xff0c;日期转换可能会遇到一些陷阱。以下是一些常见的陷阱和如何避免它们&#xff1a; 时区问题 日期和时间通常与时区相关&#xff0c;但在转换时可能会忽略或混淆时区信息。确保在转换日期时始终考虑到时区&#xff0c;并使用正确的时区进行转换。 DateTime…

vue购物车案例、v-model进阶、与后端交互

一 购物车案例 - 结算 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>购物车结算</title><script src"https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></scr…

Spark与Elasticsearch的集成与全文搜索

Apache Spark和Elasticsearch是在大数据处理和全文搜索领域中非常流行的工具。在本文中&#xff0c;将深入探讨如何在Spark中集成Elasticsearch&#xff0c;并演示如何进行全文搜索和数据分析。将提供丰富的示例代码&#xff0c;以便更好地理解这一集成过程。 Spark与Elastics…

视频监控系统EasyCVR如何通过调用API接口查询和下载设备录像?

智慧安防平台EasyCVR是基于各种IP流媒体协议传输的视频汇聚和融合管理平台。视频流媒体服务器EasyCVR采用了开放式的网络结构&#xff0c;支持高清视频的接入和传输、分发&#xff0c;平台提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联…

Zookeeper系列(一)集群搭建(非容器)

系列文章 Zookeeper系列&#xff08;一&#xff09;集群搭建&#xff08;非容器&#xff09; 目录 前言 下载 搭建 Data目录 Conf目录 集群复制和修改 启动 配置示例 测试 总结 前言 Zookeeper是一个开源的分布式协调服务&#xff0c;其设计目标是将那些复杂的且容易出错的分…

vue+springboot+mybatis实现项目管理系统

项目前端&#xff1a;https://gitee.com/anxin-personal-project/project-management-front 项目后端&#xff1a;https://gitee.com/anxin-personal-project/project-management-behind 项目均可运行&#xff01;&#xff01;&#xff01;有问题留言&#xff0c;如果看到了会…

华为mux vlan+DHCP+单臂路由用法配置案例

最终效果&#xff1a; vlan 2模拟局域网服务器&#xff0c;手动配置地址&#xff0c;也能上公网 vlan 3、4用dhcp分配地址 vlan 4的用户之间不能互通&#xff0c;但可以和其它vlan通&#xff0c;也能上公网 vlan 3的用户不受任何限制可以和任何vlan通&#xff0c;也能上公网 交…

伺服系统刚性模型的建立

一.系统工作原理 为了实现对运动控制系统精准的位置控制&#xff0c;首先要对伺服进给系统进行准确建模和模型辨识。人们对于运动控制系统的研究中已经提出了多种多样的系统建模和辨识方法。 图1 伺服电机滚珠丝杠传动系统刚性模型 下面对整个系统的工作原理进行解释&#xff…

日志系统一(elasticsearch+filebeat+logstash+kibana)

目录 一、es集群部署 安装java环境 部署es集群 安装IK分词器插件 二、filebeat安装&#xff08;docker方式&#xff09; 三、logstash部署 四、kibana部署 背景&#xff1a;因业务需求需要将nginx、java、ingress日志进行收集。 架构&#xff1a;filebeatlogstasheskib…

2024最新AI系统ChatGPT商业运营网站源码,支持Midjourney绘画AI绘画,GPT语音对话+ChatFile文档对话总结+DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…