题目链接
3335. 字符串转换后的长度 I - 力扣(LeetCode)
题目描述
给你一个字符串 s 和一个整数 t,表示要执行的 转换 次数。每次 转换 需要根据以下规则替换字符串 s 中的每个字符:
- 如果字符是
'z',则将其替换为字符串"ab"。 - 否则将其替换为字母表中的下一个字符。例如,
'a'替换为'b','b'替换为'c'。
返回 恰好 执行 t 次转换后得到的字符串的 长度。
由于答案可能非常大,返回其对 109 + 7 取余的结果。
题目示例
示例 1 :
java
输入: s = "abcyy", t = 2
输出: 7
解释:
第一次转换 (t = 1)
'a' 变为 'b'
'b' 变为 'c'
'c' 变为 'd'
'y' 变为 'z'
'y' 变为 'z'
第一次转换后的字符串为:"bcdzz"
第二次转换 (t = 2)
'b' 变为 'c'
'c' 变为 'd'
'd' 变为 'e'
'z' 变为 "ab"
'z' 变为 "ab"
第二次转换后的字符串为:"cdeabab"
最终字符串长度:字符串为 "cdeabab",长度为 7 个字符。
示例 2 :
java
输入: s = "azbk", t = 1
输出: 5
解释:
第一次转换 (t = 1)
'a' 变为 'b'
'z' 变为 "ab"
'b' 变为 'c'
'k' 变为 'l'
第一次转换后的字符串为:"babcl"
最终字符串长度:字符串为 "babcl",长度为 5 个字符。
解题思路
- 问题理解 :
- 给定一个字符串
s和变换次数t,每次变换的规则是:- 每个字母向后移动一位(
a→b,b→c,...,y→z)。 - 字母
z变为a,并且每次z变为a时会额外生成一个b。
- 每个字母向后移动一位(
- 需要计算经过
t次变换后字符串的长度。
- 给定一个字符串
- 关键思路 :
- 统计字母频率:首先统计字符串中每个字母的出现次数。
- 模拟变换过程 :
- 每次变换时,记录字母
z的数量z。 - 将所有字母向后移动一位(
a→b,b→c,...,y→z)。 - 将
z变为a(即cnt[0] = z)。 - 由于每个
z变为a时会生成一个b,因此b的数量增加z。 - 每次变换后,字符串长度增加
z(因为每个z变为a后长度不变,但会生成一个b)。
- 每次变换时,记录字母
- 算法流程 :
- 初始化字母频率数组
cnt。 - 进行
t次变换,每次变换后更新字母频率和字符串长度。 - 返回最终长度
ans。
- 初始化字母频率数组
题解代码
java
class Solution {
private final int MOD = 1000000007; // 定义模数,防止数值溢出
public int lengthAfterTransformations(String s, int t) {
// 统计字符串中每个字母的出现次数
int[] cnt = new int[26];
for (int i = 0; i < s.length(); i++) {
cnt[s.charAt(i) - 'a']++;
}
int ans = s.length(); // 初始长度为字符串长度
// 进行t次变换
while (t-- > 0) {
int z = cnt[25]; // 记录字母'z'的数量
// 将字母向后移动一位(a->b, b->c, ..., y->z)
for (int i = 24; i >= 0; i--) {
cnt[i + 1] = cnt[i];
}
cnt[0] = z; // 字母'z'变为'a'
cnt[1] = (cnt[1] + z) % MOD; // 字母'b'的数量增加z(因为每个'z'变为'a'后会生成一个'b')
ans = (ans + z) % MOD; // 每次变换后,字符串长度增加z(因为每个'z'变为'a'后长度不变,但会生成一个'b')
}
return ans;
}
}
复杂度分析
- 时间复杂度 :
- 统计字母频率:O(n),其中
n是字符串长度。 - 每次变换:
- 移动字母频率:O(26) = O(1)。
- 更新
b的数量和字符串长度:O(1)。
- 总时间复杂度:O(n + t * 26) ≈ O(n + t)。
- 统计字母频率:O(n),其中
- 空间复杂度 :
- 字母频率数组
cnt:O(26) = O(1)。 - 其他变量:O(1)。
- 总空间复杂度:O(1)。
- 字母频率数组