字典序最小的子序列

字典序最小的子序列是一個序列,它是原始序列的一部分,並且按照字典序(即字母表順序)排列。字典序的定義是,對於兩個字元串,如果第一個字元串的某個字元在第二個字元串中出現,且在第二個字元串中該字元所在的位置比在第一個字元串中更靠前,那麼第一個字元串的字典序小於第二個字元串。

例如,考慮字元串 "banana",它的字典序最小的子序列可以是 "ana",因為 "a" 出現在 "banana" 的最前面,而 "na" 是 "banana" 的子序列。

要找到一個字元串的字典序最小的子序列,通常可以使用動態規劃。我們可以定義一個狀態 dp[i] 表示字元串 s[0..i] 的字典序最小的子序列的長度。我們可以通過以下方式計算 dp[i]:

我們可以使用一個輔助數組 last 來記錄 s[0..i-1] 的字典序最小的子序列的最後一個字元的位置。last[s[i]] 表示 s[i] 在 s[0..i-1] 的字典序最小的子序列中最後一次出現的位置。

以下是一個簡單的 Python 實現:

def find_smallest_subsequence(s):
    n = len(s)
    dp = [0] * n
    last = [0] * (128)  # 假設所有字元都在 ASCII 碼錶中

    for i in range(n):
        if s[i] not in last:
            last[s[i]] = i
        else:
            last[s[i]] = min(last[s[i]], i)

    for i in range(n - 1, -1, -1):
        if i > 0 and s[i] <= s[last[s[i-1]]]:
            dp[i] = dp[last[s[i]]]
        else:
            dp[i] = 1

    return dp

# 示例
s = "banana"
print(find_smallest_subsequence(s))

這個算法的時間複雜度是 O(n),空間複雜度是 O(128),其中 128 是假設的字元集大小。如果字元集更大,空間複雜度也會相應增加。