You are given a string s
consisting of lowercase letters and an integer k
. We call a string t
ideal if the following conditions are satisfied:
t
is a subsequence of the string s
.t
is less than or equal to k
.Return the length of the longest ideal string.
A subsequence is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.
Note that the alphabet order is not cyclic. For example, the absolute difference in the alphabet order of 'a'
and 'z'
is 25
, not 1
.
Example 1:
Input: s = "acfgbd", k = 2 Output: 4 Explanation: The longest ideal string is "acbd". The length of this string is 4, so 4 is returned. Note that "acfgbd" is not ideal because 'c' and 'f' have a difference of 3 in alphabet order.
Example 2:
Input: s = "abcd", k = 3 Output: 4 Explanation: The longest ideal string is "abcd". The length of this string is 4, so 4 is returned.
Constraints:
1 <= s.length <= 105
0 <= k <= 25
s
consists of lowercase English letters.This problem asks for the length of the longest ideal subsequence in a given string s
, where an ideal subsequence satisfies two conditions:
s
.k
.The optimal approach to solve this problem is using dynamic programming. We can maintain a dp
array where dp[i]
represents the length of the longest ideal subsequence ending at index i
of string s
.
Algorithm:
Initialization: Create a dp
array of the same size as the input string s
, filled with 1s (each character itself forms a subsequence of length 1). Also create a d
dictionary (or HashMap) to store the last seen index of each character.
Iteration: Iterate through the string s
from the second character. For each character a
at index i
:
Iterate through all lowercase English letters (b
).
Check if the absolute difference between ASCII values of a
and b
is less than or equal to k
.
If true, and if b
exists in d
(meaning we've seen b
before), update dp[i]
as the maximum of dp[i]
and dp[d[b]] + 1
. This means we extend the longest subsequence ending at the last occurrence of b
.
Update d[a]
to i
, storing the last seen index of a
.
Result: After iterating through the entire string, the maximum value in the dp
array represents the length of the longest ideal subsequence.
Time Complexity: O(N*26), where N is the length of the string. The nested loop iterates through all characters of the string and all possible 26 lowercase letters in the worst-case scenario. It can be considered O(N) since 26 is a constant.
Space Complexity: O(N + 26) which is simplified to O(N), to store the dp
array and the d
dictionary (or HashMap).
class Solution:
def longestIdealString(self, s: str, k: int) -> int:
n = len(s)
ans = 1 # Initialize the answer with at least 1 (single character)
dp = [1] * n # Initialize dp array with 1s
d = {} # Dictionary to store last seen index of each character
for i in range(1, n):
a = ord(s[i]) # Get ASCII value for efficiency
for b in range(ord('a'), ord('z') + 1): # Iterate through lowercase letters
if abs(a - b) <= k: # Check condition 2
if chr(b) in d: #Check if 'b' is in dictionary
dp[i] = max(dp[i], dp[d[chr(b)]] + 1) #Update dp[i] if a longer subsequence is found
d[s[i]] = i #Update last seen index of current character
return max(dp) # Return the maximum length found in dp array
The other languages (Java, C++, Go, TypeScript) follow a very similar structure, adapting the syntax and data structures accordingly. The core dynamic programming logic remains the same. The use of ASCII values in the Python and other codes improves the efficiency of character comparisons, avoiding string comparisons repeatedly.