1946. 子字符串突变后可能得到的最大整数

题目:对数字字符串进行最大子串突变映射

题目描述

给定一个表示大整数的字符串 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 中对应的数字。
  • 替换后要求得到最大数字。
  • 替换是可选的,也可以不替换。

若不限制子串必须连续,直接把所有数字都映射替换会更简单,但这里限制了子串的连续性。


直觉和思路

为了使替换后数字尽可能大,通常我们会从字符串左边开始寻找映射后比当前数字更大的数字,这样从左到右的高位替换才有可能让整个数字更大。

一旦开始替换某个连续子串,我们需要保持替换的连续性,并且只要映射后的数字不小于原数字就继续替换。

当遇到映射数字比原数字小的情况,就结束替换,因为继续替换会导致数字变小,影响最大值。

如果整串数字替换后都不增大,则不替换。


贪心策略总结

  1. 从左到右遍历字符串。
  2. 找到第一个使映射数字 > 原数字的位置,开始替换。
  3. 替换过程中,只要映射数字 >= 原数字就继续替换。
  4. 遇到映射数字 < 原数字时停止替换。
  5. 替换结束后返回结果。

代码实现

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,结束替换
  • 最终结果 "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 和贪心策略,不断尝试替换,直到出现使结果变小的数字时停止,最终得到最大可能的数字字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值