1540. K 次操作转变字符串
大约 4 分钟
---
1540. K 次操作转变字符串
- 标签:哈希表、字符串
- 难度:中等
题目链接
题目大意
描述:给定两个字符串 和 ,以及一个整数 。每次操作可以选择一个下标 ()和一个 到 之间的整数 ,将 循环右移 步(即 )。
限制条件:
- 每个 只能被选择恰好一次。
- 同一个 值只能被使用最多一次(即所有操作中使用的 值必须互不相同)。
要求:判断能否在 次操作内将 转换为 。
说明:
- 。
- 如果 ,直接返回
False。 - 。
示例:
- 示例 1:
输入:s = "input", t = "ouput", k = 9
输出:true
解释:第 6 次操作时,我们将 'i' 切换 6 次得到 'o' 。第 7 次操作时,我们将 'n' 切换 7 次得到 'u' 。- 示例 2:
输入:s = "abc", t = "bcd", k = 10
输出:false
解释:我们需要将每个字符切换 1 次才能得到 t 。我们可以在第 1 次操作时将 'a' 切换成 'b' ,但另外 2 个字母在剩余操作中无法再转变为 t 中对应字母。解题思路
思路 1:贪心 + 计数
1. 核心思想
先检查长度是否相等。然后对于每个位置 ,计算 变成 所需的最小右移步数 :
如果 (字符已相同),该位置不需要操作。
对于 的位置,需要的 shift 值为 (因为循环移 与移 的效果相同),且每个 shift 值只能用一次。
问题转化为:对于每个需要 的位置,分配一个互不相同的 值(形式为 ,),且所有 。判断是否可行。
2. 具体步骤
第 1 步:若 ,返回 False。
第 2 步:用一个哈希表(或数组)count 统计每个 值需要被使用的次数。对于每个 ,计算 ,若 ,。
第 3 步:对于每个 ,需要的最大 shift 为:
因为同一个 的第 次出现需要 shift = ( 从 开始计数)。
第 4 步:如果所有 的 ,返回 True,否则返回 False。
3. 正确性证明
- 每个位置 需要的最小右移量 是唯一确定的。
- 由于相同的 值不能使用重复的 shift,第 次出现的 必须使用 ()。
- 最坏情况是 出现了很多次,需要的最大值为 。
- 因此只需检查所有位置所需的最大 shift 值是否 即可。
4. 举例说明
以 为例:
- :,,,需要 shift = 。
- :,,,需要 shift = 。
- :,,,需要 shift = 。
只需 才能转换成功。这里 ,返回 False。
以 为例:
- ,不需要操作。返回
True。
以 为例:
- 长度不等,返回
False。
5. 注意事项
- 最大可达 ,因此比较时直接比较数值即可,不需要遍历到 。
- 和 的长度可达 ,计数数组长度为 即可()。
思路 1:代码
class Solution:
def canConvertString(self, s: str, t: str, k: int) -> bool:
if len(s) != len(t):
return False
count = [0] * 26
for cs, ct in zip(s, t):
d = (ord(ct) - ord(cs) + 26) % 26
if d > 0:
count[d] += 1
for d in range(1, 26):
if count[d] == 0:
continue
# 第 count[d] 次出现 d 需要的 shift
needed = d + 26 * (count[d] - 1)
if needed > k:
return False
return True思路 1:复杂度分析
- 时间复杂度:, 为字符串长度。
- 空间复杂度:,计数数组。