伴学笔记:数字魔法师的进位操作
问题背景
在这个问题中,我们需要模拟一种特定的数字字符串变换魔法,即"进位操作"。每次操作会将数字字符串中的每个数字加1,并按照数字的进位规则进行变换。对于字符串中的每个数字:
- 如果数字不是9,则直接加1;
- 如果数字是9,加1后变为0,并在前面补1。
例如:
- "798" 经过一次操作会变成 "8109"(7→8, 9→0并向前增加一个1, 8→9)。
- "999" 经过一次操作会变成 "101010"。
给定一个数字字符串 num_str 和操作次数 k,我们需要计算经过 k 次操作后的最终结果,并对 1000000007 取模。
问题分析
-
字符串进位规则:
我们需要模拟进位操作。对于每个字符:- 如果是9,操作会导致其变为0,并将进位向前推送;
- 否则,数字会增加1。
-
操作次数:
我们需要对字符串执行k次这样的操作,每次操作的结果会影响后续操作,因此每一步的结果都依赖于前一轮的进位。 -
结果过大:
由于结果可能非常大,我们需要返回最终结果对1000000007取模后的值。
解题思路
-
使用队列(deque):
我们使用deque来存储数字字符串,因为队列支持高效的两端操作。这样可以方便地从队列中删除前面元素并添加进位后的元素。 -
逐步模拟进位操作:
- 每次操作从队列中取出一个数字,进行加1操作。
- 如果加1后是10,则将其变为0,并在队列的尾部添加进位(即1和0)。
- 如果不是9,直接将更新后的数字添加回队列。
-
最终结果计算:
操作完成后,我们需要将队列中的数字拼接成一个整数,并对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
代码解析
-
输入转换:
num_str是输入的数字字符串,我们使用deque将其转为数字队列。每个字符会被转换成整数,方便进行加法运算。
-
执行操作:
- 对于每一次的操作,我们遍历当前队列中的所有数字,逐个进行加1操作。
- 若加1后数字变为10,则会发生进位,进位的1被添加到队列末尾,原数字变为0。
- 若没有进位,直接更新数字并添加回队列。
-
最终结果计算:
- 操作完成后,我们从队列中逐个取出数字,按顺序拼接形成最终结果。
- 在拼接过程中,使用
(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 取模的技巧保证了计算结果的范围。