大数和中的极值位制距离| 豆包MarsCode AI 刷题

156 阅读5分钟

题目解析:大数和中的极值位制距离

小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

解题思路

1. 大数加法

由于输入的两个数是字符串表示的大数,我们不能直接将其转化为整数进行加法计算,必须模拟手动加法的过程。

细节:

  • 填充0使得两个数字长度相同:首先计算出两个输入字符串的最大长度,然后使用 zfill() 函数将较短的字符串前面补充零,确保两个字符串的长度相同,方便逐位相加。
  • 逐位加法:从右向左逐位进行加法,每次计算当前位的和并加上之前的进位(carry),然后更新进位。
  • 处理进位:如果最后的计算有进位,则在结果中添加一个额外的进位。
  • 反转结果并返回:加法完成后,结果存储在 result 中,由于我们是从右向左逐位加的,最终结果需要反转才能得到正确的数字顺序。

2. 计算最大值和最小值位置的最小差

这部分的任务是找出加法结果中最大值和最小值的最小位置差。我们需要通过遍历结果字符串,找到最大值和最小值的位置,并计算它们之间的最小差距。

细节:

  • 判断所有数字是否相同:如果加法结果中所有数字相同,那么最大值和最小值的位置差为0。
  • 找出最大和最小数字:通过内置的 max() 和 min() 函数,可以快速找出字符串中的最大和最小数字。
  • 遍历并记录位置:遍历字符串时,记录每个数字最后一次出现的位置。对于每次出现最大或最小数字时,检查另一个极值是否已经出现过。如果出现过,计算当前数字和上次出现该极值数字的距离,并更新最小距离。
  • 返回最小距离:遍历结束后,如果找到了最小距离,返回该距离;如果没有找到,则返回 len(sum_str),表示没有找到符合条件的两个极值。

3. 主函数

主函数 solution 负责调用上述两个功能模块:

  • 调用 add_large_numbers 计算两个大数相加的结果。
  • 然后调用 find_min_distance 计算加法结果中最大值和最小值之间的最小位置差,并返回该结果。

代码示例:

pythonCopy Code
def add_large_numbers(num1: str, num2: str) -> str:
    """实现大数加法"""
    # 将较短的数字在前面补0,使两个数字长度相同
    max_len = max(len(num1), len(num2))
    num1 = num1.zfill(max_len)
    num2 = num2.zfill(max_len)
    
    carry = 0  # 进位
    result = []
    
    # 从右向左逐位相加
    for i in range(max_len - 1, -1, -1):
        digit_sum = int(num1[i]) + int(num2[i]) + carry
        carry = digit_sum // 10
        result.append(str(digit_sum % 10))
    
    # 处理最后的进位
    if carry:
        result.append(str(carry))
    
    # 反转结果并转换为字符串
    return ''.join(result[::-1])

def find_min_distance(sum_str: str) -> int:
    """在结果字符串中找出最大值和最小值的最小位置差"""
    if len(set(sum_str)) == 1:  # 如果所有数字都相同
        return 0
        
    # 找到最大和最小数字
    max_digit = max(sum_str)
    min_digit = min(sum_str)
    
    # 记录每个数字最后出现的位置
    last_pos = {}
    # 记录当前找到的最小距离
    min_distance = len(sum_str)
    
    # 遍历字符串,记录位置并更新最小距离
    for i, digit in enumerate(sum_str):
        if digit == max_digit or digit == min_digit:
            # 如果另一个极值已经出现过
            for prev_digit, prev_pos in last_pos.items():
                if (digit == max_digit and prev_digit == min_digit) or \
                   (digit == min_digit and prev_digit == max_digit):
                    min_distance = min(min_distance, i - prev_pos)
            last_pos[digit] = i
            
    return min_distance - 1 if min_distance != len(sum_str) else min_distance

def solution(string1: str, string2: str) -> int:
    """主函数:计算两个大数相加后的最大最小值位置差"""
    # 计算两数之和
    sum_result = add_large_numbers(string1, string2)
    # 计算最大最小值的最小位置差
    return find_min_distance(sum_result)

总结:

  1. 大数加法:模拟手动加法过程,逐位相加并处理进位。
  2. 最小距离计算:通过遍历字符串,计算最大值和最小值之间的最小位置差。
  3. 主函数的设计:通过调用两个辅助函数,完成大数相加和位置差计算。

心得:

使用MarsCode AI编写代码让我体验到了编程的便利与高效。AI能够快速生成代码示例,帮助我理解不同编程概念。通过交互式的反馈,我能迅速调整思路,解决问题。同时,MarsCode AI提供的建议让我了解到更多最佳实践,提升了我的编码水平。这种工具不仅节省了时间,还激发了我的创造力,尤其是在处理复杂问题时,AI的支持显得尤为重要。总的来说,MarsCode AI是编程学习和实践中的得力助手。