题目:对数字字符串进行最大子串突变映射
题目描述
给定一个表示大整数的字符串 num
,以及一个长度为 10 的整数数组 change
,表示数字 0-9
的映射关系。具体来说,数字 d
映射为 change[d]
。
你可以选择 num
的任意一个连续子字符串进行 突变操作,即将子字符串中每位数字 num[i]
替换为对应的映射数字 change[num[i]]
。也可以选择不进行任何替换。
请返回在进行零次或一次突变后,能得到的 最大整数 的字符串表示。
输入输出示例
示例 1
输入:
num = "132"
change = [9,8,5,0,3,6,4,2,6,8]
输出:
"832"
解释:
替换子字符串中的数字 '1' 为 '8',因此 "132" 变为 "832",是能得到的最大整数。
示例 2
输入:
num = "021"
change = [9,4,3,5,7,2,1,9,0,6]
输出:
"934"
解释:
替换整个字符串 "021":
0 → 9, 2 → 3, 1 → 4,
所以得到 "934",最大。
示例 3
输入:
num = "5"
change = [1,4,7,5,3,2,5,6,9,4]
输出:
"5"
解释:
替换后数字不变或变小,保持原样即可。
解题分析
这道题的关键点在于:
- 只能替换一个连续的子串。
- 替换子串内的每个数字都会映射为
change
中对应的数字。 - 替换后要求得到最大数字。
- 替换是可选的,也可以不替换。
若不限制子串必须连续,直接把所有数字都映射替换会更简单,但这里限制了子串的连续性。
直觉和思路
为了使替换后数字尽可能大,通常我们会从字符串左边开始寻找映射后比当前数字更大的数字,这样从左到右的高位替换才有可能让整个数字更大。
一旦开始替换某个连续子串,我们需要保持替换的连续性,并且只要映射后的数字不小于原数字就继续替换。
当遇到映射数字比原数字小的情况,就结束替换,因为继续替换会导致数字变小,影响最大值。
如果整串数字替换后都不增大,则不替换。
贪心策略总结
- 从左到右遍历字符串。
- 找到第一个使映射数字
>
原数字的位置,开始替换。 - 替换过程中,只要映射数字
>=
原数字就继续替换。 - 遇到映射数字
<
原数字时停止替换。 - 替换结束后返回结果。
代码实现
from typing import List
class Solution:
def maximumNumber(self, num: str, change: List[int]) -> str:
num_list = list(num)
started = False # 标记是否开始替换
for i in range(len(num_list)):
digit = int(num_list[i])
mapped_digit = change[digit]
if mapped_digit > digit:
# 开始替换子串
num_list[i] = str(mapped_digit)
started = True
elif mapped_digit == digit and started:
# 替换中,数字相等,继续替换
num_list[i] = str(mapped_digit)
elif mapped_digit < digit and started:
# 替换结束,跳出循环
break
# 如果没开始替换且映射数字不大于原数字,继续寻找起点
return "".join(num_list)
复杂度分析
- 时间复杂度:
O(n)
,遍历一次字符串num
。 - 空间复杂度:
O(n)
,存储转换后的字符数组。
示例演示
以示例1为例:
- 输入:
num = "132"
,change = [9,8,5,0,3,6,4,2,6,8]
- 遍历过程:
- i=0,数字1 → 映射8,大于1,开始替换,结果变成
"832"
- i=1,数字3 → 映射0,小于3,结束替换
- i=0,数字1 → 映射8,大于1,开始替换,结果变成
- 最终结果
"832"
以示例2为例:
- 输入:
num = "021"
,change = [9,4,3,5,7,2,1,9,0,6]
- i=0,数字0 → 9,大于0,开始替换
- i=1,数字2 → 3,大于2,继续替换
- i=2,数字1 → 4,大于1,继续替换
- 替换结束,结果为
"934"
代码优势与拓展
- 该方法贪心直接,逻辑清晰易懂。
- 只遍历一次字符串,性能高效。
- 易于维护和扩展,比如如果题目变成允许多次替换,则需要改策略。
总结
本题考察贪心思想在字符串操作中的应用。关键在于合理定位开始和结束替换的时机,从左向右遍历字符串,同时保证替换的连续性和最大化结果。
通过映射数组 change
和贪心策略,不断尝试替换,直到出现使结果变小的数字时停止,最终得到最大可能的数字字符串。