问题描述
小R面对一个问题,她有两个由数字字符组成的超大字符串数,需要求出这两个数相加后得到的字符串数中的最大数和最小数之间的位数差距。如果结果中所有数字都相同,则差距为 0。如果存在多个符合最大或最小条件的数,应该选择最小的位置差。
例如,字符串数 "111" 和 "222" 相加得到 "333",所有数字相同,因此位数差为 0。另一例子,字符串数 "111" 和 "34" 相加得到 "145",其中最大数是 '5' 位于第 3 位,最小数是 '1' 位于第 1 位,他们之间的位差为 1。
测试样例
样例1:
输入:
string1 = "111",string2 = "222"
输出:0
样例2:
输入:
string1 = "111",string2 = "34"
输出:1
样例3:
输入:
string1 = "999",string2 = "1"
输出:0
样例4:
输入:
string1 = "525",string2 = "474"
输出:0
思考
我们需要处理两个由数字字符组成的超大字符串数,并求出这两个数相加后得到的字符串数中的最大数和最小数之间的位数差距。如果结果中所有数字都相同,则差距为 0。若有多个最大或最小数字,选择最左边的数字计算位差。
解决过程
-
字符串相加:
- 首先,将输入的两个字符串数转换为整数,相加后再将结果转换为字符串。Python内置的
int()函数非常强大,可以处理任意长度的整数,因此直接用int(string1) + int(string2)就能得到正确的结果。
- 首先,将输入的两个字符串数转换为整数,相加后再将结果转换为字符串。Python内置的
-
检查数字一致性:
- 使用一个简单的条件
all(c == total[0] for c in total)来检查结果字符串中是否所有字符都相同。如果相同,则直接返回 0,因为位差为 0。
- 使用一个简单的条件
-
找出最大和最小数字:
- 使用
max(total)和min(total)找到结果字符串中的最大和最小字符。这些函数遍历整个字符串,返回其中最大的字符和最小的字符。
- 使用
-
收集位置:
- 使用列表推导式
[i+1 for i, c in enumerate(total) if c == max_digit]和[i+1 for i, c in enumerate(total) if c == min_digit]分别找出字符串中最大和最小数字的位置。这里位置是1-based,因此我们在索引上加一。
- 使用列表推导式
-
计算最小位差:
- 初始化最小位差为无穷大
min_diff = float('inf')。 - 双重循环遍历最大和最小数字的所有位置,计算每一对位置之间的位差
diff = abs(pos_max - pos_min) - 1。 - 更新
min_diff,如果位差为0,立即返回0,因为此时已经找到最小可能位差。 - 返回最小位差。
- 初始化最小位差为无穷大
注意事项
- 边界情况:需要考虑字符串相加后所有数字相同的情况,这种情况下,提前返回0可以节省计算资源。
- 位置计算的准确性:在计算位差时,注意位置是从1开始而不是0。这需要在记录位置时加1,以避免错误的计算。
- 性能优化:虽然双重循环的复杂度为O(n^2),但由于大部分情况下,最大和最小数字不多,所以这种方法在实际中性能较好。如果最大和最小数字很多,可能需要更复杂的数据结构来优化
复杂度分析
-
时间复杂度:
- 加法操作:O(n),其中n为较长字符串的长度。
max()和min()操作:每个都是O(n)。- 位置收集:O(n)。
- 计算最小位差:最坏情况下O(k^2),其中k是最大或最小数字的个数。
-
空间复杂度:
- 常数级别的额外空间用于存储位置列表和结果字符串,O(n)额外空间用于存储结果字符串。
Solution代码
def solution(string1, string2):
# 计算两数之和
total = str(int(string1) + int(string2))
# 检查所有数字是否相同
if all(c == total[0] for c in total):
return 0
max_digit = max(total)
min_digit = min(total)
# 收集最大数字和最小数字的所有位置(1-based)
max_positions = [i+1 for i, c in enumerate(total) if c == max_digit]
min_positions = [i+1 for i, c in enumerate(total) if c == min_digit]
# 计算最小位差
min_diff = float('inf')
for pos_max in max_positions:
for pos_min in min_positions:
diff = abs(pos_max - pos_min) - 1
if diff < min_diff:
min_diff = diff
if min_diff == 0:
return 0
return min_diff
if __name__ == "__main__":
print(solution("111", "222") == 0)
print(solution("111", "34") == 1)
print(solution("999", "1") == 0)
print(solution("525", "474") == 0)
print(solution("5976762424003073", "6301027308640389") == 6)