📌  相关文章
📜  国际空间研究组织 | ISRO CS 2020 |问题 15(1)

📅  最后修改于: 2023-12-03 15:07:35.146000             🧑  作者: Mango

ISRO CS 2020 | Problem 15

题目描述

给定一个长度为 $n$ 的非空字符串 $s$,请你找到最长的非空子序列 $t$,使得 $t$ 中的字符都可以写成 $s$ 的某个前缀的形式。

输入格式

输入包含一个字符串 $s$,该字符串由小写字母组成,$1 \leq n \leq 10^5$。

输出格式

输出一个字符串,表示最长的符合条件的子序列 $t$。如果有多个解,输出其中任意一个。

样例输入
babab
样例输出
bab
说明

字符串 $s$ 的所有前缀为 ${\textbf{b},ba,\textbf{bab},baba,babab}$,可以构成的子序列为:

  • $\textbf{b}$
  • $ba$
  • $\textbf{bab}$
  • $baba$
  • $\textbf{bab},ba$
  • $\textbf{bab},baba$
  • $ba,baba$
  • $\textbf{bab},ba,baba$
  • $\textbf{bab},ba,baba,babab$

最长的符合条件的子序列为 $\textbf{bab}$。

解题思路

对于任意字符串 $s$,其所有前缀的集合中必然包含一个最长的非空前缀 $p$ 和一个非空后缀 $q$,满足 $p = q$。

因此,我们可以从 $s$ 的开头和结尾同时开始遍历,遇到相同字符时就把它加入到答案中。直到两个指针相遇,或者两个指针指向了同一个字符,即找到了最长的符合条件的子序列。

详见以下 Python 代码实现:

def longest_prefix_suffix(s):
    res, i, j = "", 0, len(s) - 1
    while i <= j:
        if i == j and s[i] == s[0]:
            return res + s[i]
        if s[i] == s[j]:
            res += s[i]
            i += 1
            j -= 1
        else:
            if s[i + 1] == s[i]:
                i += 1
            elif s[j - 1] == s[j]:
                j -= 1
            else:
                i += 1
    return res
复杂度分析
  • 时间复杂度:$O(n)$,其中 $n$ 是字符串 $s$ 的长度。两个指针同时遍历,每次可以移动一个位置。
  • 空间复杂度:$O(1)$,只需要常数级别的额外空间。