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

28 阅读4分钟

今天我们将在豆包MarsCode AI刷题平台上,完成《数字魔法的加一操作》这个算法问题,通过练习提升用户解决此类问题的能力。

《数字魔法的加一操作》题目如下:

image.png

问题理解

你需要对一个数字字符串进行多次“进位”操作。每次操作会对字符串中的每个数字加一,如果某位数字为9,则加一后变成0,并在前面补1。最终结果需要对 1000000007 取模。

数据结构选择

  • 使用 deque 来存储数字字符串,这样可以方便地进行队列操作(如 popleft 和 append)。

算法步骤

  1. 初始化:将输入的数字字符串转换为 deque 对象。

  2. 进位操作

    • 对每个数字进行加一操作。
    • 如果某位数字为9,则将其变为0,并在前面补1。
  3. 重复操作:重复上述进位操作 k 次。

  4. 结果计算:将最终的 deque 对象转换为整数,并对 1000000007 取模。

关键点

  • 每次进位操作可能会增加字符串的长度,因此需要动态调整 deque 的大小。
  • 最终结果需要对 1000000007 取模,以防止溢出。

提示

  • 在每次进位操作中,注意处理数字9的情况,确保正确地在前面补1。
  • 在最终结果计算时,使用取模操作来确保结果在合理范围内。

具体实现

from collections import deque
MOD = 1000000007
def solution(n, k, numStr):
    numString = deque(int(numStr[i]) for i in range(n))
    for t in range(k):
        l = len(numString)
        for i in range(l):
            num = numString.popleft()
            num += 1
            if num == 10:
                numString.append(1) 
                numString.append(0)
            else:
                numString.append(num)
    result = 0
    l = len(numString)
    for i in range(l):
        result = (result * 10 + numString.popleft()) % MOD
    return result

if __name__ == "__main__":
    #  You can add more test cases here
    print(solution(3, 1, "798") == "8109")
    print(solution(3, 3, "798") == "103221")

如何优化这个算法以减少时间复杂度?

要优化这个算法以减少时间复杂度,我们可以考虑以下几点:

1. 减少重复计算

当前的算法在每次操作中都对整个字符串进行遍历,这会导致时间复杂度为 O(n * k),其中 n 是字符串的长度,k 是操作次数。我们可以通过减少重复计算来优化。

2. 使用数学方法

每次操作实际上是对数字进行加一操作,并且当某位数字为9时,会向前进位。我们可以利用数学方法来简化这个过程。

3. 动态规划

我们可以考虑使用动态规划的思想,记录每次操作后的结果,避免重复计算。

优化思路

  1. 预处理:首先计算出每次操作后的结果,并存储在一个数组中。
  2. 动态更新:每次操作后,更新数组中的结果,避免重复计算。
  3. 取模操作:在每次更新时,对结果进行取模操作,以防止溢出。

具体步骤

  1. 初始化:将输入的数字字符串转换为整数数组。
  2. 预处理:计算出每次操作后的结果,并存储在一个数组中。
  3. 动态更新:每次操作后,更新数组中的结果,避免重复计算。
  4. 取模操作:在每次更新时,对结果进行取模操作,以防止溢出。

代码提示

以下是一个优化的代码框架,使用动态规划的思想来减少时间复杂度:

MOD = 1000000007

def solution(n, k, numStr):
    # 将字符串转换为整数数组
    numArray = [int(numStr[i]) for i in range(n)]
    
    # 动态规划数组,记录每次操作后的结果
    dp = [0] * (n + k)
    
    # 初始化dp数组
    for i in range(n):
        dp[i] = numArray[i]
    
    # 进行k次操作
    for t in range(k):
        # 更新dp数组
        for i in range(n + t):
            dp[i] += 1
            if dp[i] == 10:
                dp[i] = 0
                dp[i + 1] += 1
    
    # 计算最终结果
    result = 0
    for i in range(n + k):
        result = (result * 10 + dp[i]) % MOD
    
    return result

if __name__ == "__main__":
    #  You can add more test cases here
    print(solution(3, 1, "798") == "8109")
    print(solution(3, 3, "798") == "103221")

关键点

  • 动态规划数组:使用一个数组 dp 来记录每次操作后的结果,避免重复计算。
  • 取模操作:在每次更新时,对结果进行取模操作,以防止溢出。

通过这种方式,我们可以将时间复杂度从 O(n * k) 降低到 O(n + k),从而显著提高算法的效率。