1540. K 次操作转变字符串

字符串转换挑战:在有限操作次数内将字符串 s 转变成 t


题目描述

给定两个字符串 st,以及一个操作次数上限 k,目标是在 不超过 k 次操作 的情况下,将字符串 s 转变成字符串 t

每次操作有以下规则:

  • i 次操作(1 <= i <= k)可以选择字符串 s之前未被操作过 的任意一个字符位置 j (1-based 下标),对该位置的字符进行切换操作。
  • 切换操作含义是将字符切换 i 次,即在字母表中将该字符向后移动 i 个字母,字母表循环连接:z 后接 a
  • 也可以选择不操作。

注意:

  • 每个位置的字符最多只能被操作一次。
  • 需要判断是否能在 k 次操作内完成转换。

解题分析

这道题看起来非常特殊,因为每次操作的“切换次数”跟操作的顺序紧密相关:第 i 次操作必须切换 i 次字符。我们无法随意选择切换次数,只能和当前操作次数对应。

关键点

  • 字符变化由 s[i] 转到 t[i] 的距离决定,记为 d = (ord(t[i]) - ord(s[i])) % 26
  • 字符必须通过一次操作完成,且这次操作的编号 i 需要满足 i % 26 == d,因为切换操作是环绕字母表的。
  • 每个差值 d 可能会出现多次,我们需要安排足够多的操作次数满足所有相同差值的字符变化。
  • 每个位置只能操作一次,意味着不能重复使用同一次操作编号。

解题方法

核心思路

  1. 计算字符差值

st 逐字符计算差值 d,即:

d = (ord(t[i]) - ord(s[i])) % 26

如果 d == 0,表示该字符不需变化,跳过。

  1. 统计每个差值出现的次数

使用一个字典或 Counter 来统计每个差值 d 出现的频率 freq

验证操作次数安排的可行性

因为第 i 次操作对应切换 i 次字符,且切换是模 26 的环状字母表,所有满足条件的 i 必须满足:

  1. i \equiv d \pmod{26}

因此,对于频率为 freq 的差值 d,操作次数 i 可以依次为:

  1. d, d + 26, d + 52, \ldots, d + 26 \times (freq - 1)

即第一个满足 d 的操作是 d,第二个是 d+26,依此类推。

判断最大所需操作编号是否超过 k

如果最大操作编号:

  1. d + 26 \times (freq - 1) \leq k

对所有差值都成立,则可以在 k 次操作内完成转换。


代码实现

from collections import Counter

class Solution:
    def canConvertString(self, s: str, t: str, k: int) -> bool:
        if len(s) != len(t):
            return False

        diff_counter = Counter()

        for i in range(len(s)):
            d = (ord(t[i]) - ord(s[i])) % 26
            if d != 0:
                diff_counter[d] += 1

        for d, freq in diff_counter.items():
            max_time_needed = d + 26 * (freq - 1)
            if max_time_needed > k:
                return False

        return True

思路分析与比较

  • 暴力搜索法:考虑所有可能的操作顺序和选择,复杂度极高,不可行。
  • 贪心 + 数学分析:本题关键在于理解每次操作“切换次数”的唯一性及循环性质。利用模运算关系和计数,贪心分配满足条件的操作编号,达到最优解。
  • 复杂度:遍历字符串 O(n),统计次数 O(n),判断 O(26),整体为 O(n),效率高。

这种数学分析加贪心策略解决了问题的约束条件和操作唯一性。


示例说明

示例 1

s = "aab"
t = "bbb"
k = 27
  • 对每个字符计算差值 d
    • abd = 1
    • abd = 1
    • bbd = 0,不需变化
  • 差值统计:{1: 2}
  • 最大操作编号:1 + 26 * (2 - 1) = 1 + 26 = 27 <= k,符合条件,返回 True

示例 2

s = "input"
t = "ouput"
k = 9
  • 差值计算(简化示意):

位置 1 (i): io 差值较大,超过9,无法完成

  • 在有限的9次操作内无法覆盖大差值,返回 False

总结

这道题虽然规则复杂,但通过数学分析,利用模运算周期性计数分配思想,可以快速判断是否能完成转换。

关键点是理解:

  • 每次操作必须使用对应的切换次数 i
  • 字符切换次数与操作编号的模26关系,
  • 每个差值操作的编号必须分散开(相差26)。

这也是算法中常见的周期性调度与计数应用的经典案例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值