力扣第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

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

MyBatis-Plus使用动态表名分表查询的实现

《MyBatis-Plus使用动态表名分表查询的实现》本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录1. 引入依赖2. myBATis-plus配置3. TenantContext 类:租户上下文

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js