📅  最后修改于: 2023-12-03 15:10:19.891000             🧑  作者: Mango
在程序开发中,面对各种复杂的数据结构和算法问题是常见的挑战。本文将介绍一个常见的问题,以及解决该问题的一些方法。
问题 9:给定一个字符串,找到其中最长的不包含重复字符的子串。例如,在字符串 "abcabcbb" 中,最长的不包含重复字符的子串为 "abc"。
暴力解决该问题的方法是枚举所有可能的子串并比较它们是否重复。时间复杂度为 $O(n^3)$ ,容易超时。
滑动窗口是一种比较高效的解决方法。我们可以用两个指针 left 和 right 来划定一个窗口,然后根据窗口中的字符判断是否重复,如果重复,则移动 left ,否则移动 right。
时间复杂度为 $O(n)$ ,可以通过该方法解决该问题。
def lengthOfLongestSubstring(s: str) -> int:
n = len(s)
ans = 0
left, right = 0, 0
visited = set()
while left < n and right < n:
if s[right] not in visited:
visited.add(s[right])
right += 1
ans = max(ans, right - left)
else:
visited.remove(s[left])
left += 1
return ans
我们可以用一个长度为 $n$ 的列表 dp 来表示以每个字符为结尾的最长不重复子串的长度。我们可以枚举字符串中的每个字符,然后判断它是否在以前一个字符结尾的不重复子串中出现过,如果出现过,则从该位置开始重新计算不重复子串的长度,否则将以前一个字符结尾的最长不重复子串长度加 1。
时间复杂度为 $O(n)$ ,可以通过该方法解决该问题。
def lengthOfLongestSubstring(s: str) -> int:
n = len(s)
if n == 0:
return 0
dp = [0] * n
dp[0] = 1
visited = {s[0]}
ans = 1
for i in range(1, n):
if s[i] not in visited:
visited.add(s[i])
dp[i] = dp[i - 1] + 1
else:
j = i - 1
while j >= i - dp[i - 1]:
if s[j] == s[i]:
break
visited.remove(s[j])
j -= 1
dp[i] = i - j
ans = max(ans, dp[i])
return ans
本文介绍了一个常见的字符串问题,以及三种解决方法:暴力法、滑动窗口和动态规划。其中,滑动窗口和动态规划是比较高效的解决方法。在实际开发中,应该根据实际情况来选择合适的解决方法。