We define the string base
to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz"
, so base
will look like this:
"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...."
.Given a string s
, return the number of unique non-empty substrings of s
are present in base
.
Example 1:
Input: s = "a" Output: 1 Explanation: Only the substring "a" of s is in base.
Example 2:
Input: s = "cac" Output: 2 Explanation: There are two substrings ("a", "c") of s in base.
Example 3:
Input: s = "zab" Output: 6 Explanation: There are six substrings ("z", "a", "b", "za", "ab", and "zab") of s in base.
Constraints:
1 <= s.length <= 105
s
consists of lowercase English letters.This problem asks to find the number of unique non-empty substrings of a given string s
that are present in the infinite wraparound string "abcdefghijklmnopqrstuvwxyz...". A naive approach would involve generating all substrings and checking if each is a substring of the wraparound string, leading to high time complexity. A more efficient dynamic programming approach is used here.
The solution leverages dynamic programming to avoid redundant calculations. It utilizes an array f
of size 26 (one for each lowercase letter), where f[i]
stores the maximum length of a substring ending with the i-th letter (considering the wraparound).
Initialization: f
is initialized with all zeros.
Iteration: The code iterates through the input string s
. For each character c
:
k
(representing the length of the current consecutive substring) is incremented. Otherwise, k
is reset to 1.f[c]
is updated to the maximum of its current value and k
, ensuring we only track the maximum length of a consecutive substring ending with c
.Result: Finally, the sum of all elements in f
is returned. This sum represents the total number of unique substrings.
Time Complexity: O(n), where n is the length of the input string s
. The code iterates through the string once.
Space Complexity: O(1). The space used by the f
array is constant (26 elements), regardless of the input string size. Note that even though some implementations (like Python's) use a dictionary (hashmap), the space used by that dictionary is also bounded by a constant (26) in this case.
from collections import defaultdict
class Solution:
def findSubstringInWraproundString(self, s: str) -> int:
f = defaultdict(int) # Use defaultdict for easy handling of missing keys
k = 0
for i, c in enumerate(s):
if i > 0 and (ord(c) - ord(s[i - 1])) % 26 == 1: # Check for consecutive sequence (wraparound considered)
k += 1
else:
k = 1
f[c] = max(f[c], k) # Update f[c] with the maximum length of a substring ending in c
return sum(f.values()) # Return the sum of all lengths in f
The other language implementations follow the same algorithm, with minor syntax differences to handle array indexing, string manipulation, and maximum/sum calculations in their respective languages. The core logic remains consistent across all implementations.