拆分成最多数目的正偶数之和
一、题目
给你一个整数 finalSum
。请你将它拆分成若干个互不相同
的正偶数之和,且拆分出来的正偶数数目最多
。
比方说,给你 finalSum = 12
,那么这些拆分是符合要求
的(互不相同的正偶数且和为 finalSum):(2 + 10) ,(2 + 4 + 6) 和 (4 + 8) 。它们中,(2 + 4 + 6) 包含最多数目的整数。注意finalSum
不能拆分成(2 + 2 + 4 + 4)
,因为拆分出来的整数必须互不相同。
请你返回一个整数数组,表示将整数拆分成最多
数目的正偶数数组。如果没有办法将finalSum
进行拆分,请你返回一个空
数组。你可以按任意
顺序返回这些整数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-split-of-positive-even-integers
二、思路
2.1 贪心算法
- 为什么贪心算法要叫这个名字?本来贪心是用来形容欲望大,不知足。这里,贪心是指每一步都贪图
当前最优
的选择,即局部最优解,而不考虑
该选择对后续步骤的影响。 - 举个非常简单的例子:假设现在有
4
张钞票:1元、5元、10元和20元,现在允许你每次拿1
张,最多拿2
张,你会怎么拿才能让自己得到最多的钱? - 一年级的小朋友都知道,肯定要从大的面值开始拿,也就是先拿20元,再拿10元。最后就能得到30元巨款。其实这就是贪心算法的核心思想:
贪图当前最优
。
2.2 确定算法
- 回到题目,为什么这个题能用贪心算法进行求解?或者往大了说,我们什么时候应该想到使用贪心算法进行求解?
- 对于贪心算法,我们需要知道一点:
不保证最优解
,什么意思?大白话说就是可能得到的答案是错误的
!所以在应用贪心算法之前,我们要仔细分析问题,并判断是否适合使用贪心算法。 - 一般来说,如果题目满足下面的条件,我们可以选取贪心算法求解:
- 问题具有贪心选择性质:通过局部最优的选择达到全局最优,也就是说最优解不需要进行全局考虑。
- 问题的子问题相互独立:当前的选择不会影响后续的选择。
- 来看本题目:
- 要拆分 finalSum,并取得
最大
的拆分数目,并且拆分出来的偶数互不相同
。我们希望拆分成尽可能多的偶数,所以应该尽可能拆份成最小的若干个偶数。这样就满足了问题具有贪心选择性质
的特点。 - 当前的选择也并不会影响之后的选择,满足了
问题的子问题相互独立
的特点。所以自然而然,我们想到了使用贪心算法进行求解。
- 要拆分 finalSum,并取得
三、详细算法
3.1 算法分析
- 前面分析了为什么要使用贪心算法,接下来看一下具体的实现步骤。
- 从
最小的偶整数2
开始依次尝试拆分,直到剩余的数值小于等于
当前被拆分的最大偶整数
为止。 此时,我们已经拆分成尽可能多的偶数,不可能拆分出更多的互不相同的偶数。 - 如果此时拆分后剩余的 finalSum 大于零,则将这个数值加到最大的偶整数上,从而保证所有的数互不相同。
- 从
- 还是举个例子可能会更清楚一点。比如拿
32
来拆分。- 取
2
,此时 finalSum = 30ans = [2]
- 取
4
,此时 finalSum = 26ans = [2,4]
- 取
6
,此时 finalSum = 20ans = [2,4,6]
- 取
8
,此时 finalSum = 12ans = [2,4,6,8]
- 取
10
,此时 finalSum = 2ans = [2,4,6,8,10]
- 这时,能取的最小偶数已经比剩下的数还大了
(10 > 2)
,自然已经无法进行拆分了,最后将剩下的2
加在当前的最大值10
上面,这样可以保证结果不重复。 - 最终我们得到了正确结果(之一):
[2,4,6,8,12]
- 取
3.2 详细题解
1 | class Solution { |
四、总结
- 看得出来贪心算法并不是很难,因为在相对较难(限制较多)的题目中,由于贪心算法无法保证最优解,是不能使用的。
- 贪心算法虽然简单,但它仍然是一种重要的算法思想,它有简单易实现、效率高等特点。并且在某些不需要追求最优解只需要近似最优解的情况下,贪心算法可以发挥其优势。
- 对于贪心算法受限的问题,通常需要考虑其他算法,如动态规划、回溯法等,来找到最优解。这些算法可能更加复杂,但它们可以解决那些贪心算法无法处理的问题。