Skip to content

2370 Longest Ideal Subsequence

Approach 1 TLE

Same as LIS, but input size is \(10^5\), which means it only takes up to \(O(n)\) or \(O(nlogn)\) time complexity. This one is \(O(n^2)\), so it will TLE.

class Solution:
    def longestIdealString(self, s: str, k: int) -> int:
        n = len(s)
        dp = [1 for _ in range(n)]

        for i in range(1,n):
            for j in range(i):
                if abs(ord(s[i]) - ord(s[j])) <= k:
                    dp[i] = max(dp[i],dp[j]+1)

        return max(dp)

Approach 2

abcda and abcca has the same length. Whether it's a valid subsequence or not, only depends on the most adjacent pair, so our state can be simplified to a 26 x 26 size array.

We only need 26 x 26 states to describe all the possible subsequence. However, we can simplify it even further to a 1-D array of 26. Since we don't really even care the first character, we only care about the previous character to see if we can insert anything into it. Therefore, a 1D array is enough to describe the state.

dp = [0] * 26

Algorithm:

  • initialize an array of 26 with zeros. indicate we haven't seen any character yet.
  • iterate through the string \(O(n)\)
    • iterate through every alphabets character, we find the longest previous character that can be inserted into it \(O(26)\)
    • update the current character's value with the candidate (previous character + 1)
    • update the result to the maximum value of the current character

Code Implementation

class Solution:
    def longestIdealString(self, s: str, k: int) -> int:
        """
        - highly likely a DP since subsequence;
        - 脑补一下的话,是一条曲折的线,然后画y = a to y = a+k 之间所有的线,找到经过最多的交点;
        """
        n = len(s)
        dp = [0] * 26
        res = 0
        for i in range(n):
            curr = ord(s[i]) - ord('a')
            best = 0
            # 找到符合条件的,上一个最大的值
            for prev in range(26):
                if abs(prev - curr) <= k:
                    best = max(best,dp[prev])
            # subsequence ending with s[i], update it
            dp[curr] = max(dp[curr],best+1)
            res = max(res,dp[curr])
        return res