📅  最后修改于: 2023-12-03 15:22:35.293000             🧑  作者: Mango
在字符串中找到一个长度最长的子串,满足该子串中的字符不重复。
例如:
输入: aghdgfhk
输出: hdgfk (长度为5)
最简单的做法是暴力枚举所有可能的子串,并检查子串中是否有重复的字符。这种方法的时间复杂度为O(n^3),虽然简单易懂,但效率较低,仅适用于较短的字符串。
def longest_non_repeat_substring(s: str) -> str:
n = len(s)
ans = ""
for i in range(n):
for j in range(i+1, n+1):
if len(set(s[i:j])) == j-i:
if len(ans) < len(s[i:j]):
ans = s[i:j]
return ans
由于暴力解法效率较低,我们需要尝试更快的算法。滑动窗口是一种常见的解题方法,可以在O(n)的时间内解决此问题。我们使用两个指针,左右指针构成一个窗口,窗口中的字符不重复,右指针向右移动时,窗口向右滑动,左指针向右移动时,窗口缩小。我们根据窗口中字符数量的多少,判断是否更新最长子串。
例如:输入 'dababcd'
def longest_non_repeat_substring(s: str) -> str:
n = len(s)
ans = ""
i = 0
j = 0
seen = set()
while i < n and j < n:
if s[j] not in seen:
seen.add(s[j])
j += 1
ans = max(ans, s[i:j], key=len)
else:
seen.remove(s[i])
i += 1
return ans
滑动窗口算法的时间复杂度是O(n),空间复杂度是O(min(n, m)),其中m是字符集的大小。如果字符集大小是常数级别,那么空间复杂度是O(1)。我们可以说这是一种线性时间复杂度的算法,算法的实际速度由输入字符串的长度决定。