Leetcode 3337. Total Characters in String After Transformations II
Table of Contents
Problem Informations
- Problem Index: 3337
- Problem Link: Total Characters in String After Transformations II
- Topics: Hash Table, Math, String, Dynamic Programming, Counting
Problem Description
You are given a string s
consisting of lowercase English letters, an integer t
representing the number of transformations to perform, and an array nums
of size 26. In one transformation, every character in s
is replaced according to the following rules:
- Replace
s[i]
with the nextnums[s[i] - 'a']
consecutive characters in the alphabet. For example, ifs[i] = 'a'
andnums[0] = 3
, the character'a'
transforms into the next 3 consecutive characters ahead of it, which results in"bcd"
. - The transformation wraps around the alphabet if it exceeds
'z'
. For example, ifs[i] = 'y'
andnums[24] = 3
, the character'y'
transforms into the next 3 consecutive characters ahead of it, which results in"zab"
.
Return the length of the resulting string after exactly t
transformations.
Since the answer may be very large, return it modulo $10^9 + 7$.
Example 1:
Input: s = "abcyy"
, t = 2
, nums = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2]
Output: 7
Explanation:
First Transformation (t = 1):
'a'
becomes'b'
asnums[0] == 1
'b'
becomes'c'
asnums[1] == 1
'c'
becomes'd'
asnums[2] == 1
'y'
becomes'z'
asnums[24] == 1
'y'
becomes'z'
asnums[24] == 1
- String after the first transformation:
"bcdzz"
Second Transformation (t = 2):
'b'
becomes'c'
asnums[1] == 1
'c'
becomes'd'
asnums[2] == 1
'd'
becomes'e'
asnums[3] == 1
'z'
becomes'ab'
asnums[25] == 2
'z'
becomes'ab'
asnums[25] == 2
- 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
, nums = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
Output: 8
Explanation:
First Transformation (t = 1):
'a'
becomes'bc'
asnums[0] == 2
'z'
becomes'ab'
asnums[25] == 2
'b'
becomes'cd'
asnums[1] == 2
'k'
becomes'lm'
asnums[10] == 2
- String after the first transformation:
"bcabcdlm"
Final Length of the string: The string is
"bcabcdlm"
, which has 8 characters.
Constraints:
- $1 \leq s.length \leq 10^5$
s
consists only of lowercase English letters.- $1 \leq t \leq 10^9$
nums.length == 26
- $1 \leq nums[i] \leq 25$
Intuition
The problem requires transforming each character in a string s
through a series of transformations defined by an integer array nums
and an integer t
, which dictates how many transformations to apply. Each transformation changes a character to a sequence of subsequent characters in the alphabet based on the nums
array. The challenge lies in handling the potentially exponential growth of the string due to repeated transformations, especially given the constraints that allow a large number of transformations (t
up to $10^9$).
The key to solving this problem is recognizing that the direct simulation of transformations up to t
is infeasible due to both time and space constraints. Instead, this problem can be addressed through matrix exponentiation, which allows us to efficiently compute the result of multiple transformations compactly.
Approach
The approach utilizes linear algebra concepts, particularly focusing on matrix multiplication and exponentiation to efficiently compute the result of t
transformations.
Initial State Representation:
- Start by representing the string
s
as a frequency vectorinitialCount
, which is a 26-dimensional vector (since there are 26 lowercase English letters). Each element at indexi
in the vector represents the count of the letteri + 'a'
ins
.
- Start by representing the string
Transformation Matrix Construction:
- Construct a 26x26 transformation matrix
M
where each row represents the result of transforming a particular character according tonums
. Specifically, if characteri
is transformed based onnums[i]
, the matrix entryM[(i + j) % 26][i]
is set to 1 for eachj
from 1 tonums[i]
. This encapsulates wrapping around the alphabet.
- Construct a 26x26 transformation matrix
Matrix Exponentiation:
- Compute the matrix
M
raised to the powert
, denoted asM^t
. This operation, done efficiently using exponentiation by squaring, gives us the effect of performingt
transformations in a compact form.
- Compute the matrix
Final Transformation Application:
- Multiply the matrix
M^t
by the initial frequency vectorinitialCount
to get a new vectorfinalCount
. Each entry infinalCount
represents the count of each character aftert
transformations.
- Multiply the matrix
Calculate the Final Length:
- Sum all elements in
finalCount
to determine the total length of the transformed string. Since the length may be large, take the result modulo $10^9 + 7$ to ensure it fits within the constraints.
- Sum all elements in
This matrix exponentiation approach efficiently computes the effect of multiple transformations without explicitly expanding the string, which is crucial given the potential for exponential growth in string length.
Code
C++
#include <array>
#include <vector>
#include <string>
using namespace std;
class Solution {
static constexpr long long MOD = 1'000'000'007;
using Mat = array<array<long long, 26>, 26>; // Alias for a 26x26 matrix type
using Vec = array<long long, 26>; // Alias for a 26-element vector type
/* -------- Matrix Operations -------- */
// Matrix Multiplication: Multiplies two 26x26 matrices A and B
static Mat mulMat(const Mat& A, const Mat& B) {
Mat C{}; // Resulting matrix initialized to zero
for (int i = 0; i < 26; ++i)
for (int k = 0; k < 26; ++k)
if (A[i][k]) {
long long aik = A[i][k];
for (int j = 0; j < 26; ++j) {
C[i][j] += aik * B[k][j] % MOD;
if (C[i][j] >= MOD)
C[i][j] -= MOD; // Ensure C[i][j] is within MOD
}
}
return C;
}
// Matrix-Vector Multiplication: Multiplies matrix A with vector v
static Vec mulMatVec(const Mat& A, const Vec& v) {
Vec res{}; // Resulting vector initialized to zero
for (int i = 0; i < 26; ++i) {
long long sum = 0;
for (int j = 0; j < 26; ++j) {
sum += A[i][j] * v[j] % MOD;
if (sum >= MOD)
sum -= MOD; // Ensure sum is within MOD
}
res[i] = sum;
}
return res;
}
// Matrix Exponentiation: Computes base^exp using matrix exponentiation by squaring
static Mat matPow(Mat base, int exp) {
Mat ret{}; // Identity matrix initialization
for (int i = 0; i < 26; ++i)
ret[i][i] = 1;
while (exp) {
if (exp & 1)
ret = mulMat(ret, base);
base = mulMat(base, base);
exp >>= 1;
}
return ret;
}
public:
int lengthAfterTransformations(string s, int t, vector<int>& nums) {
// 1. Convert the initial string into a 26-dimensional frequency vector
Vec initialCount{};
for (char c : s)
initialCount[c - 'a']++;
// 2. Build the 26x26 transformation matrix M for one transformation
Mat M{}; // Initialize to zero
for (int i = 0; i < 26; ++i)
for (int j = 1; j <= nums[i]; j++)
M[(i + j) % 26][i] = 1;
// 3. Compute M^t (M raised to the power of t)
Mat Mt = matPow(M, t);
// 4. Multiply the resulting transformation matrix with the initial vector
// and sum up the elements to get the final length
Vec finalCount = mulMatVec(Mt, initialCount);
long long result = 0;
for (long long x : finalCount) {
result += x;
if (result >= MOD)
result -= MOD; // Ensure result is within MOD
}
return static_cast<int>(result);
}
};
Python
from typing import List
class Solution:
MOD = 1_000_000_007
@staticmethod
def mulMat(A, B):
C = [[0] * 26 for _ in range(26)] # Resulting matrix initialized to zero
for i in range(26):
for k in range(26):
if A[i][k]:
aik = A[i][k]
for j in range(26):
C[i][j] += aik * B[k][j] % Solution.MOD
if C[i][j] >= Solution.MOD:
C[i][j] -= Solution.MOD # Ensure C[i][j] is within MOD
return C
@staticmethod
def mulMatVec(A, v):
res = [0] * 26 # Resulting vector initialized to zero
for i in range(26):
sum = 0
for j in range(26):
sum += A[i][j] * v[j] % Solution.MOD
if sum >= Solution.MOD:
sum -= Solution.MOD # Ensure sum is within MOD
res[i] = sum
return res
@staticmethod
def matPow(base, exp):
ret = [[0] * 26 for _ in range(26)] # Identity matrix initialization
for i in range(26):
ret[i][i] = 1
while exp:
if exp & 1:
ret = Solution.mulMat(ret, base)
base = Solution.mulMat(base, base)
exp >>= 1
return ret
def lengthAfterTransformations(self, s: str, t: int, nums: List[int]) -> int:
# 1. Convert the initial string into a 26-dimensional frequency vector
initialCount = [0] * 26
for c in s:
initialCount[ord(c) - ord('a')] += 1
# 2. Build the 26x26 transformation matrix M for one transformation
M = [[0] * 26 for _ in range(26)] # Initialize to zero
for i in range(26):
for j in range(1, nums[i] + 1):
M[(i + j) % 26][i] = 1
# 3. Compute M^t (M raised to the power of t)
Mt = self.matPow(M, t)
# 4. Multiply the resulting transformation matrix with the initial vector
# and sum up the elements to get the final length
finalCount = self.mulMatVec(Mt, initialCount)
result = 0
for x in finalCount:
result += x
if result >= self.MOD:
result -= self.MOD # Ensure result is within MOD
return result
Complexity
Time complexity: $O(26^3 \log t + n)$
The time complexity can be broken down into distinct parts:
- Matrix Multiplication and Exponentiation: The matrix multiplications (both matrix-matrix and matrix-vector product) involve 26x26 matrices, leading to $O(26^3)$ operations per multiplication. Matrix exponentiation using exponentiation by squaring requires $\log t$ multiplications, resulting in $O(26^3 \log t)$ time complexity.
- Initial Vector Setup and Final Calculation: Creating the initial frequency vector requires traversing the string
s
, which takes $O(n)$. The final length is calculated by summing elements of the resulting vector, effectively another $O(26)$ operation, which is negligible compared to matrix operations.
Thus, the overall time complexity is dominated by the matrix operations, i.e., $O(26^3 \log t + n)$.
Space complexity: $O(26^2)$
The space complexity is determined by storing the 26x26 transformation matrix and additional vectors used during calculations:
- Matrix Storage: The primary space is consumed by the 26x26 matrix, which is $O(26^2)$.
- Vector Storage: Frequency vectors are of size 26, i.e., $O(26)$, but they are significantly smaller than matrix storage.
As the matrix’s space requirement dominates, the space complexity is $O(26^2)$.
Disclaimer: All reference materials on this website are sourced from the internet and are intended for learning purposes only. If you believe any content infringes upon your rights, please contact me at csnote.cc@gmail.com, and I will remove the relevant content promptly.
Feedback Welcome: If you notice any errors or areas for improvement in the articles, I warmly welcome your feedback and corrections. Your input will help this blog provide better learning resources. This is an ongoing process of learning and improvement, and your suggestions are valuable to me. You can reach me at csnote.cc@gmail.com.