Watch 10 video solutions for Longest Ideal Subsequence, a medium level problem involving Hash Table, String, Dynamic Programming. This walkthrough by NeetCodeIO has 13,159 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
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 <= 1050 <= k <= 25s consists of lowercase English letters.Problem Overview: You are given a string s and an integer k. A subsequence is considered ideal if the absolute difference between the positions of every pair of adjacent characters in the alphabet is at most k. The task is to return the length of the longest such subsequence you can build from s.
This is fundamentally a constrained subsequence problem. You want the longest chain where each new character can only extend subsequences ending with characters within a limited alphabet distance. The constraint ties the problem directly to dynamic programming over characters.
Approach 1: Dynamic Programming with Character Indexing (Time: O(n * 26), Space: O(26))
Track the best subsequence length that ends with each letter of the alphabet. Maintain an array dp[26] where dp[i] stores the longest ideal subsequence ending with character ('a' + i). Iterate through the string and map each character to its alphabet index.
For the current character c, check all characters within the valid range [c - k, c + k]. The maximum value among those entries represents the best subsequence that can be extended. Update dp[c] to max(dp[c], best + 1). Since the alphabet size is fixed at 26, the inner scan is constant time. This keeps the algorithm linear with respect to the string length.
This approach works well because it converts a subsequence dependency into a small state transition over the alphabet. Instead of tracking subsequences for every index, you only store the best result per character. The idea is a classic pattern in string problems that combine ordering constraints with limited character sets.
Approach 2: Optimized Use of HashMap (Time: O(n * 26), Space: O(26))
This variant replaces the fixed array with a HashMap or dictionary keyed by characters. For each character in the string, check all characters whose alphabet distance is within k. Look up their current best subsequence length in the map and compute the best extension.
Update the map entry for the current character with the new maximum length. Conceptually the algorithm is identical to the array approach, but the map structure makes the implementation flexible when the character domain is not strictly limited or when the language favors dictionary-style lookups.
The main operations are hash lookups and updates, which remain constant time on average. This pattern frequently appears in problems involving character transitions and frequency tracking, making it closely related to techniques used in hash table based dynamic programming.
Recommended for interviews: The array-based dynamic programming approach is what most interviewers expect. It shows that you recognize the small fixed alphabet and compress the DP state into 26 buckets instead of tracking every subsequence explicitly. A brute-force subsequence search would be exponential and impractical. The optimized DP demonstrates strong pattern recognition and the ability to reduce a problem to constant-sized state transitions.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Dynamic Programming with Character Indexing | O(n * 26) | O(26) | Best general solution when the alphabet is fixed (lowercase letters). Fast and memory efficient. |
| Optimized HashMap Approach | O(n * 26) | O(26) | Useful when implementing with dynamic character sets or when dictionary lookups are preferred. |