本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。
为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。
由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。
给你一个正整数 num
,请你将它分割成两个非负整数 num1
和 num2
,满足:
num1
和num2
直接连起来,得到num
各数位的一个排列。- 换句话说,
num1
和num2
中所有数字出现的次数之和等于num
中所有数字出现的次数。
- 换句话说,
num1
和num2
可以包含前导 0 。
请你返回 num1
和 num2
可以得到的和的 最小 值。
注意:
num
保证没有前导 0 。num1
和num2
中数位顺序可以与num
中数位顺序不同。
示例 1:
输入:num = 4325
输出:59
解释:我们可以将 4325 分割成 `num1` = 24 和 num2 `=` 35 ,和为 59 ,59 是最小和。
示例 2:
输入:num = 687
输出:75
解释:我们可以将 687 分割成 `num1` = 68 和 `num2` = 7 ,和为最优值 75 。
提示:
10 <= num <= 10^9
解法 贪心:排序+奇偶分组
思考: 4325 4325 4325 怎么分?
如果分成 432 432 432 和 5 5 5 这两组,不如分成 32 32 32 和 45 45 45,因为 4 4 4 在 432 432 432 中是 400 400 400 ,在 45 45 45 中是 40 40 40 。这启发我们要尽量均匀分。如果有奇数个数,多出的那个数放在哪一组都可以。
如果均匀分成 32 32 32 和 45 45 45 这两组,那么 32 32 32 这组调整一下顺序, 23 23 23 比 32 32 32 更好。
进一步地,均匀分成 24 24 24 和 35 35 35 更好,也就是把小的数字排在高位,大的数字排在低位。
设 s s s 是 n u m num num 的字符串形式,这等价于把 s s s 排序后,按照奇偶下标分组。
class Solution {
public:
int splitNum(int num) {
string s = to_string(num);
sort(s.begin(), s.end());
int a[2]{};
for (int i = 0; i < s.length(); i++)
a[i % 2] = a[i % 2] * 10 + s[i] - '0'; // 按照奇偶下标分组
return a[0] + a[1];
}
};
复杂度分析:
- 时间复杂度: O ( m log m ) \mathcal{O}(m\log m) O(mlogm) ,其中 mmm 为 n u m num num 转成字符串后的长度。
- 空间复杂度: O ( m ) \mathcal{O}(m) O(m) 。