Problem Statement
You are given a string s
and an integer t
, representing the number of transformations to perform. In one transformation, every character in s
is replaced according to the following rules:
- If the character is
z
, replace it with the string"ab"
. - Otherwise, replace it with the next character in the alphabet. For example,
'a'
is replaced with‘b’
,'b'
is replaced with'c'
, and so on.
Return the length of the resulting string after exactly t
transformations.
Since the answer may be very large, return it modulo
10^9 + 7
.
LeetCode
Constraints
1 <= s.length <= 10^5
s consists only of lowercase English letters.
1 <= t <= 10^5
1 ≤ s.length ≤ 10^5
- The length of string
s
can be up to100,000
characters.- Since the length can be up to
10^5
, you cannot affordO(n^2)
(quadratic) time complexity – it will timeout (TLE). - You should aim for:
O(n)
linearO(n log n)
linearithmic- or at most
O(k * n)
wherek
is small (e.g., 26 for lowercase characters)
- Since the length can be up to
- The length of string
s
consists of only lowercase english letters:- There are only 26 unique characters to consider.
1 ≤ t ≤ 10^5
Examples
Example 1:
Input: s = "abcyy", t = 2
Output: 7
Explanation:
First Transformation (t = 1):
'a' becomes 'b'
'b' becomes 'c'
'c' becomes 'd'
'y' becomes 'z'
'y' becomes 'z'
String after the first transformation: "bcdzz"
Second Transformation (t = 2):
'b' becomes 'c'
'c' becomes 'd'
'd' becomes 'e'
'z' becomes "ab"
'z' becomes "ab"
String after the second transformation: "cdeabab"
Final Length of the string: The string is "cdeabab", which has 7 characters.
Example 2:
Input: s = "azbk", t = 1
Output: 5
Explanation:
First Transformation (t = 1):
'a' becomes 'b'
'z' becomes "ab"
'b' becomes 'c'
'k' becomes 'l'
String after the first transformation: "babcl"
Final Length of the string: The string is "babcl", which has 5 characters.
Different Approaches
1️⃣ Brute Force Approach
Idea:
Try all transformation
Code:
class Solution {
public:
// This function applies a transformation `t` times on string `s`
// and returns the final length of the transformed string.
int lengthAfterTransformations(string s, int t) {
// Repeat the transformation `t` times
for (int round = 0; round < t; round++) {
string transformedString = "";
// Go through each character in the current string
for (char currentChar : s) {
// If the character is 'z', replace it with "ab"
if (currentChar == 'z') {
transformedString += "ab";
} else {
// Otherwise, increment the character by one in the alphabet
// For example, 'a' becomes 'b', 'b' becomes 'c', ..., 'y' becomes 'z'
transformedString += currentChar + 1;
}
}
// Update the original string with the new transformed version
s = transformedString;
}
// Return the length of the final string after all transformations
return s.size();
}
};
Complexity Analysis:
- Time Complexity:
O(n * 2 ^ t)
- At each transformation round, you go through every character in the string and possibly increase the length.
- Worst case: All characters are
z
.- In each round, every
z
becomesab
– string length doubles - So after
t
rounds, length becomesO(n * 2 ^ t)
- In each round, every
- Space Complexity:
O(n × 2^t)
- You create a new string temp in each round (of length up to n × 2^t in the worst case).
2️⃣ Better Approach
Code:
class Solution {
public:
// A constant MOD value to prevent integer overflow in large calculations
static constexpr int MOD = 1'000'000'007;
// Function to compute the length of the string after 't' transformations
int lengthAfterTransformations(string s, int t) {
// Step 1: Create a frequency map of characters in the input string
unordered_map<char, int> charFrequency;
for (char ch : s) {
charFrequency[ch]++;
}
// Step 2: Apply transformations for 't' rounds
for (int i = 0; i < t; i++) {
// Temporary map to store updated character frequencies after this round
unordered_map<char, int> tempFrequency;
// Traverse through current frequency map
for (auto entry : charFrequency) {
char ch = entry.first;
int count = entry.second;
// If the character is not 'z', simply increment the character
if (ch != 'z') {
tempFrequency[ch + 1] = (tempFrequency[ch + 1] + count) % MOD;
}
// If the character is 'z', replace it with "ab"
else {
tempFrequency['a'] = (tempFrequency['a'] + count) % MOD;
tempFrequency['b'] = (tempFrequency['b'] + count) % MOD;
}
}
// Move updated frequencies to the main map for the next round
charFrequency = move(tempFrequency);
}
// Step 3: Compute the total number of characters after all transformations
int finalLength = 0;
for (auto entry : charFrequency) {
finalLength = (finalLength + entry.second) % MOD;
}
return finalLength;
}
};
Complexity Analysis:
3️⃣ Optimized Approach
Code:
class Solution {
public:
// Constant to take modulo and prevent overflow on large counts
static constexpr int MOD = 1'000'000'007;
// Function to return the length of the string after `t` transformations
int lengthAfterTransformations(string s, int t) {
// Step 1: Create a frequency array for all lowercase letters (a-z)
// Index 0 for 'a', 1 for 'b', ..., 25 for 'z'
vector<int> frequency(26, 0);
// Count initial frequency of each character in the string
for (char ch : s) {
frequency[ch - 'a']++;
}
// Step 2: Apply `t` rounds of transformation
for (int i = 0; i < t; i++) {
// Create a new frequency array for this round
vector<int> tempFrequency(26, 0);
// Iterate through each character a to z (represented as index 0 to 25)
for (int idx = 0; idx < 26; idx++) {
int count = frequency[idx]; // Count of current character
char ch = idx + 'a'; // Convert index back to character
if (ch != 'z') {
// If current character is not 'z', increment the character
// For example, 'a' becomes 'b', 'b' becomes 'c', etc.
tempFrequency[ch + 1 - 'a'] = (tempFrequency[ch + 1 - 'a'] + count) % MOD;
} else {
// Special case: if character is 'z', it becomes "ab"
tempFrequency['a' - 'a'] = (tempFrequency['a' - 'a'] + count) % MOD;
tempFrequency['b' - 'a'] = (tempFrequency['b' - 'a'] + count) % MOD;
}
}
// Move new frequencies to the main array for the next round
frequency = move(tempFrequency);
}
// Step 3: Calculate the final string length
int totalLength = 0;
for (int i = 0; i < 26; i++) {
totalLength = (totalLength + frequency[i]) % MOD;
}
return totalLength;
}
};
Complexity Analysis:
- Time Complexity:
O(t)
- Each transformation step runs in
O(26)
- Total time for
t
transformations:O(26 * t) = O(t)
- Each transformation step runs in
- Space Complexity:
O(1)
- Uses two fixed-size arrays of 26 elements.