力扣第343题 整数拆分 c++ 动态规划 + 贪心巧解

2023-11-01 13:20

本文主要是介绍力扣第343题 整数拆分 c++ 动态规划 + 贪心巧解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

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。

提示:

  • 2 <= n <= 58

思路和解题方法(已优化)

  1. 首先,我们定义一个一维数组dp,其中dp[i]表示将正整数i拆分成若干个正整数的和后,这些正整数的乘积的最大值。
  2. 接下来,我们进行动态规划的计算。外层循环从3开始,因为对于小于等于2的正整数,无法拆分成多个正整数的和,所以最大乘积就是其本身。内层循环从1遍历到i / 2,表示在正整数i上进行拆分。
  3. 对于每个内层循环中的位置(i, j),我们有两种选择:要么将正整数i拆分成长度为j和(i-j)的两个正整数,要么不再进行拆分。如果选择拆分,那么乘积就是(i - j) * j;如果选择不再拆分,那么乘积就是dp[i - j] * j。我们需要取这两者之间的较大值,然后更新dp[i]
  4. 最终,当外层循环结束时,dp[n]就表示将正整数n拆分成若干个正整数的和后,这些正整数的乘积的最大值。

复杂度

        时间复杂度:

                O(n^2)

  1. 时间复杂度为O(n^2),因为有两层循环嵌套。其中,外层循环从3到n,内层循环从1到i / 2

        空间复杂度

                O(n)

空间复杂度为O(n),因为只使用了一个大小为n+1的一维数组dp

c++ 代码

class Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1); // 创建一个大小为n+1的一维数组dp,用于存储拆分整数i后的最大乘积dp[2] = 1; // 对于整数2,无法进行拆分,最大乘积就是其本身for (int i = 3; i <= n ; i++) { // 从3开始遍历到nfor (int j = 1; j <= i / 2; j++) { // 在整数i上进行拆分,内层循环从1遍历到i/2// 选择将整数i拆分成长度为j和(i-j)的两个部分或者不再进行拆分,取两者之间的较大值dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));}}return dp[n]; // 返回将整数n拆分成若干个正整数之和后,这些正整数的乘积的最大值}
};

附贪心思维

解释

  1. 首先处理一些特殊情况,当n等于2、3、4时,直接返回对应的结果,因为这些情况无法再进行拆分。
  2. 初始化一个变量result为1,用于保存最终的乘积结果。
  3. 当n大于4时,不断循环执行以下步骤:
    • result乘以3,表示将n拆分出一个长度为3的部分。
    • 将n减去3,表示已经拆分出了一个长度为3的部分。
  4. 循环结束后,剩余的n的取值只能是2、3或者4。将result乘以剩余的n,得到最终的乘积结果。
  5. 返回最终的乘积结果。
class Solution {
public:int integerBreak(int n) {if (n == 2) return 1;  // 对于整数2,无法进行拆分,最大乘积就是其本身(1 * 1 = 1)if (n == 3) return 2;  // 对于整数3,可以拆分为1 + 2,乘积为1 * 2 = 2if (n == 4) return 4;  // 对于整数4,可以拆分为2 + 2,乘积为2 * 2 = 4int result = 1;while (n > 4) {result *= 3;  // 每次将n拆分成3的部分,因为3的乘积比其他数字更大n -= 3;}result *= n;  // 最后剩下的n小于等于4,直接乘到结果中return result;}
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

这篇关于力扣第343题 整数拆分 c++ 动态规划 + 贪心巧解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/323262

相关文章

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下: