数字魔法的加一操作| 豆包MarsCode AI刷题

62 阅读4分钟

伴学笔记:数字魔法师的进位操作

问题背景

在这个问题中,我们需要模拟一种特定的数字字符串变换魔法,即"进位操作"。每次操作会将数字字符串中的每个数字加1,并按照数字的进位规则进行变换。对于字符串中的每个数字:

  • 如果数字不是9,则直接加1;
  • 如果数字是9,加1后变为0,并在前面补1。

例如:

  • "798" 经过一次操作会变成 "8109"(7→8, 9→0并向前增加一个1, 8→9)。
  • "999" 经过一次操作会变成 "101010"。

给定一个数字字符串 num_str 和操作次数 k,我们需要计算经过 k 次操作后的最终结果,并对 1000000007 取模。

问题分析

  1. 字符串进位规则:
    我们需要模拟进位操作。对于每个字符:

    • 如果是9,操作会导致其变为0,并将进位向前推送;
    • 否则,数字会增加1。
  2. 操作次数:
    我们需要对字符串执行 k 次这样的操作,每次操作的结果会影响后续操作,因此每一步的结果都依赖于前一轮的进位。

  3. 结果过大:
    由于结果可能非常大,我们需要返回最终结果对 1000000007 取模后的值。

解题思路

  1. 使用队列(deque):
    我们使用 deque 来存储数字字符串,因为队列支持高效的两端操作。这样可以方便地从队列中删除前面元素并添加进位后的元素。

  2. 逐步模拟进位操作:

    • 每次操作从队列中取出一个数字,进行加1操作。
    • 如果加1后是10,则将其变为0,并在队列的尾部添加进位(即1和0)。
    • 如果不是9,直接将更新后的数字添加回队列。
  3. 最终结果计算:
    操作完成后,我们需要将队列中的数字拼接成一个整数,并对 1000000007 取模。

Python代码实现

from collections import deque

MOD = 1000000007

def solution(n, k, num_str):
    # 将数字字符串转换成队列,其中每个元素是一个整数
    numString = deque(int(num_str[i]) for i in range(n))
    
    # 执行 k 次操作
    for t in range(k):
        l = len(numString)
        for i in range(l):
            num = numString.popleft()  # 从队列中取出一个数字
            num += 1  # 增加1
            if num == 10:  # 如果加1后是10,则产生进位
                numString.append(1)  # 添加进位的1
                numString.append(0)  # 添加进位后的0
            else:
                numString.append(num)  # 否则只加上新值
    
    # 计算最终结果
    result = 0
    while numString:
        result = (result * 10 + numString.popleft()) % MOD  # 将队列中的数字拼接成整数并对MOD取模

    return result

# 测试代码
if __name__ == "__main__":
    print(solution(3, 1, "798"))  # 期望输出: 8109
    print(solution(3, 3, "798"))  # 期望输出: 103221

代码解析

  1. 输入转换:

    • num_str 是输入的数字字符串,我们使用 deque 将其转为数字队列。每个字符会被转换成整数,方便进行加法运算。
  2. 执行操作:

    • 对于每一次的操作,我们遍历当前队列中的所有数字,逐个进行加1操作。
    • 若加1后数字变为10,则会发生进位,进位的1被添加到队列末尾,原数字变为0。
    • 若没有进位,直接更新数字并添加回队列。
  3. 最终结果计算:

    • 操作完成后,我们从队列中逐个取出数字,按顺序拼接形成最终结果。
    • 在拼接过程中,使用 (result * 10 + num) % MOD 来防止溢出,并保持结果对 1000000007 取模。

复杂度分析

  • 时间复杂度:

    • 每次操作对队列进行遍历和更新。对于每个操作,我们遍历 n 次,最多执行 k 次操作。因此,时间复杂度是 O(k * n)
  • 空间复杂度:

    • 我们使用一个队列存储数字,空间复杂度是 O(n),其中 n 是数字字符串的长度。

测试用例

print(solution(3, 1, "798"))  # 期望输出: 8109
print(solution(3, 3, "798"))  # 期望输出: 103221
print(solution(3, 0, "798"))  # 期望输出: 798 (没有进行操作)
print(solution(4, 5, "9999")) # 期望输出: 1010101010

总结

本题考察了字符串操作、队列应用和进位规则的实现。通过队列的有效使用,我们能够高效地模拟进位操作,并且使用对 1000000007 取模的技巧保证了计算结果的范围。