力扣第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#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.