经常性的刷题经常性的遗忘,想来想去就写个博客记录下自己这个菜鸟的点点滴滴吧
1.问题描述
给你一个整数
finalSum
。请你将它拆分成若干个互不相同的正偶数之和,且拆分出来的正偶数数目最多 。比方说,给你
finalSum = 12
,那么这些拆分是符合要求的(互不相同的正偶数且和为finalSum
):(2 + 10)
,(2 + 4 + 6)
和(4 + 8)
。它们中,(2 + 4 + 6)
包含最多数目的整数。注意finalSum
不能拆分成(2 + 2 + 4 + 4)
,因为拆分出来的整数必须互不相同。请你返回一个整数数组,表示将整数拆分成最多数目的正偶数数组。如果没有办法将
finalSum
进行拆分,请你返回一个空数组。你可以按任意顺序返回这些整数。
2.示例
示例 1:
输入:finalSum = 12 输出:[2,4,6] 解释:以下是一些符合要求的拆分:(2 + 10),(2 + 4 + 6) 和 (4 + 8) 。 (2 + 4 + 6) 为最多数目的整数,数目为 3 ,所以我们返回 [2,4,6] 。
[2,6,4] ,[6,2,4] 等等也都是可行的解。示例 2:
输入:finalSum = 7 输出:[] 解释:没有办法将 finalSum 进行拆分。 所以返回空数组。示例 3:
输入:finalSum = 28 输出:[6,8,2,12] 解释:以下是一些符合要求的拆分:(2 + 26),(6 + 8 + 2 + 12) 和 (4 + 24) 。 (6 + 8 + 2 + 12)
有最多数目的整数,数目为 4 ,所以我们返回 [6,8,2,12] 。 [10,2,4,12] ,[6,2,4,16] 等等也都是可行的解。提示:
1 <= finalSum <= 10^10
问题分析(基本是胡扯):
读完题目我们不难理解,偶数+偶数一定是偶数,所以如果finalSum的值为奇数,那么我们肯定是无法通过偶数相加获得,因此直接返回空数组。
注意到题目还有一个条件:拆分出来的正偶数数目最多 。所以我们希望,从小的开始加,能加多少个加多少个,比如50,我们2+4+6+8+10+12=42<50, 再加14就大于50了,因此我们发现我们最多加到它的前一个也就是10这个数字,又因为数组的最后一个数字x一定满足2+4+6+8+10+x=50这个条件,因此我们直接能倒推出x具体的值。
基于上述思考,我们就可以开始写代码了。
class Solution {
public:
vector<long long> maximumEvenSplit(long long finalSum) {
vector<long long> vec;
if(finalSum % 2 == 1) return vector<long long>();
else
{
long long presum = 0;
int i = 2;
while(presum < finalSum)
{
presum += i;
vec.push_back(i);
i += 2;
}
//如果我们正好加到的presum==finalSum,那这个就是我们要求的最大数组
if(presum == finalSum)
return vec;
//大于了,我们就倒退前两个,通过一元一次方程解出我们需要的x,得到最大数组
else if(presum > finalSum)
{
i -= 2;
vec.pop_back();
vec.pop_back();
presum -= i;
i -= 2;
presum -= i;
vec.push_back(finalSum - presum);
}
}
return vec;
}
};