题目描述
给你一个四位 正 整数 num
。请你使用 num
中的 数位 ,将 num
拆成两个新的整数 new1
和 new2
。new1
和 new2
中可以有 前导 0 ,且 num
中** 所有** 数位都必须使用。
比方说,给你 num = 2932
,你拥有的数位包括:两个 2
,一个 9
和一个 3
。一些可能的 [new1, new2]
数对为 [22, 93]
,[23, 92]
,[223, 9]
和 [2, 329]
。
请你返回可以得到的 new1
和 new2
的 最小 和。
示例
示例1
输入:num = 2932
输出:52
解释:可行的 [new1, new2] 数对为 [29, 23] ,[223, 9] 等等。
最小和为数对 [29, 23] 的和:29 + 23 = 52 。
示例2
输入:num = 4009
输出:13
解释:可行的 [new1, new2] 数对为 [0, 49] ,[490, 0] 等等。
最小和为数对 [4, 9] 的和:4 + 9 = 13 。
提示
1000 <= num <= 9999
解题思路
暴力法
对于这一题,刚开始我的思路就是直接暴力,用dfs找出所有的可能的组合,然后找出其中和最小的,不过由于太懒了,那样写起来也很麻烦,所以我就仔细想了一下,发现因为题目给我们的一定是一个四位数,而要想得到这两个数的和最小,那么这两个数一定都是两位数,所以我们的dfs就更好写了,我们看下面这张图
我们假设分别里面的元素依次为第一个数num1, 第二个数num2, 剩余的数位lst,我们将前2层(包括第2层)得到的数位给第一个数,后面的给第二个数,这样我们就可以得到所有的两位数的组合,最后返回和最小的那个值就行了,这个方法的具体代码请见Python的代码
数学
当我后面用C++做的时候(因为对C++)不熟悉,所以就去看了一下题解,以为会和我的想法一样,结果才发现,我那个笨蛋思路压根多此一举,后面的代码我便先依次取得每一个数位存放在一个容器中(数组、vector),然后对这个容器进行排序,将最小的两个数相加起来乘以10就可以得到最小的两个数的十位数之和,将较大的两个数位加起来就可以得到两个数的个位之和,最后的结果就是我们要的答案,我们设这个四位数是abcd
用数学符号表示就是
(
a
∗
10
+
b
)
+
(
c
∗
10
+
d
)
=
(
a
+
c
)
∗
10
+
b
+
d
\ (a * 10 + b) +( c * 10 + d) = (a + c) * 10 + b + d
(a∗10+b)+(c∗10+d)=(a+c)∗10+b+d
接下来请看具体AC代码
AC代码
Python
class Solution:
def minimumSum(self, num: int) -> int:
lst = [int(i) for i in str(num)]
return self.bfs(1, 0, 0, lst)
def bfs(self, i: int, num1: int, num2: int, lst: List[int]) -> int:
if i > 4:
return num1 + num2
min_value = 10000
for j in lst:
if i <= 2:
a = num1 * 10 + j
cur_lst = lst.copy()
cur_lst.remove(j)
value = self.bfs(i + 1, a, num2, cur_lst)
else:
a = num2 * 10 + j
cur_lst = lst.copy()
cur_lst.remove(j)
value = self.bfs(i + 1, num1, a, cur_lst)
min_value = min_value if min_value < value else value
return min_value
C
qsort函数
在 C 语言中,qsort 函数是一个标准库函数,用于对数组进行快速排序(Quick Sort)。它位于 stdlib.h 头文件中,是 C 语言标准库中提供的排序函数之一。
函数原型如下:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
参数说明:
base:指向待排序数组的首元素的指针。
nmemb:数组中的元素数量(即数组的长度)。
size:每个元素的大小(以字节为单位)。
compar:指向比较函数的指针。该函数用于确定元素的顺序。
它接收两个指向待比较元素的指针,并返回一个整数值来表示它们之间的关系。
比较函数的格式为:
int compar(const void *a, const void *b);
返回值说明:
负数:表示第一个元素a小于第二个元素b。在升序排序中,这意味着a应该排在b之前
0:表示两个数相等,表示在排序后的结果中保持原来的相对顺序
正数:表示第一个数a大于第二个元素b。在升序排序中,这意味着a应该排在b之后
int compare(const void *a, const void *b)
{
int num1 = *(const int *)a;
int num2 = *(const int *)b;
return num1 - num2;//这里如果想要进行降序排序,则可以用num2 - num1
}
int minimumSum(int num){
int nums[4];
for(int i=0;i<4;i++)
{
nums[i] = num % 10;
num /= 10;
}
qsort(nums, 4, sizeof(int), compare);
return (nums[0] + nums[1]) * 10 + nums[2] + nums[3];
}
C++
class Solution {
public:
int minimumSum(int num) {
vector<int> nums;
while(num != 0)
{
int a = num % 10;
nums.push_back(a);
num /= 10;
}
sort(nums.begin(), nums.end());
return (nums[0] + nums[1]) * 10 + nums[2] + nums[3];
}
};
Java
class Solution {
public int minimumSum(int num) {
int[] nums = new int[4];
for (int i = 0; i < nums.length; i++) {
nums[i] = num % 10;
num /= 10;
}
Arrays.sort(nums);
return (nums[0] + nums[1]) * 10 + nums[2] + nums[3];
}
}