📌  相关文章
📜  最长的子字符串,其任何非空子字符串都不是给定字符串的前缀或后缀(1)

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

最长的子字符串,其任何非空子字符串都不是给定字符串的前缀或后缀

给定一个字符串,找到其中最长的子字符串,该子字符串的任何非空子字符串都不是给定字符串的前缀或后缀。

解法

首先,我们可以考虑使用动态规划来解决这个问题。

假设 f[i] 表示以第 i 个字符结尾的最长的子字符串,该子字符串的任何非空子字符串都不是该字符串的前缀或后缀。

那么我们可以得到状态转移方程:

  • 如果 s[i] 之前没有出现过,则 f[i] = f[i-1] + 1
  • 如果 s[i] 之前出现过,则 f[i] 的值需要重新计算。假设 js[i] 上一次出现的位置,则有 f[i] = i - j

最终,最长的子字符串即为所有 f[i] 中的最大值。

我们可以用一个哈希表来记录每个字符上一次出现的位置,从而在计算 f[i] 时可以快速找到上一次出现的位置。

代码

下面是使用 Python 实现的代码:

def longest_substring(s: str) -> int:
    n = len(s)
    last = {}
    f = [0] * n
    max_len = 0
    for i in range(n):
        if s[i] not in last:
            f[i] = f[i-1] + 1
        else:
            j = last[s[i]]
            if j < i - f[i-1]:
                f[i] = f[i-1] + 1
            else:
                f[i] = i - j
        last[s[i]] = i
        max_len = max(max_len, f[i])
    return max_len
性能分析

该算法的时间复杂度为 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度为 $O(n)$。因此,该算法在处理长度较大的字符串时非常高效。