最小和分割【LC2578】
给你一个正整数
num
,请你将它分割成两个非负整数num1
和num2
,满足:
- num1和 num2直接连起来,得到 num各数位的一个排列。
- 换句话说,
num1
和num2
中所有数字出现的次数之和等于num
中所有数字出现的次数。num1
和num2
可以包含前导 0 。请你返回
num1
和num2
可以得到的和的 最小 值。注意:
num
保证没有前导 0 。num1
和num2
中数位顺序可以与num
中数位顺序不同。
-
思路
- 局部最优:统计num中每个数字的出现次数,从0开始逐位构造,使两个数字的最高位最小
- 全局最优:使num1和num2的和最小
-
实现
class Solution { public int splitNum(int num) { // 贪心构造:高位一定是较小值 int[] count = new int[10]; while(num > 0){ count[num % 10]++; num /= 10; } int num1 = 0, num2 = 0; int index = 0, i = 0; while (i < 10){ if (count[i] == 0){ i++; }else if ((index & 1) == 0){ num1 = num1 * 10 + i; count[i]--; index++; }else{ num2 = num2 * 10 + i; count[i]--; index++; } } return num1 + num2; } }
- 复杂度
- 时间复杂度: O ( log n u m ) \mathcal{O}(\log {num} ) O(lognum)
- 空间复杂度: O ( C ) \mathcal{O}(C) O(C)
- 复杂度