题目描述
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度,返回其长度。
示例
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: s = ""
输出: 0
思路
题目是让我们找出不包含重复元素的最长子串,那么一次遍历就够了,只要碰到重复元素,便直接取当前子串重复元素之后的部分继续往后遍历,最终选择最长的子串即可。比如s = ‘abcabc’,假设我们当前遍历到了第一个’c’,那么当前子串为’abc’,下一元素为’a’,可见’a’已经存在于当前子串’abc’里了,我们便去除重复元素,在当前子串中取‘bc’(去掉’a’),然后继续往下遍历。直到遍历到s的最后一个元素,找出具有最大长度的子串即可。
代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 获取字符串s的长度
n = len(s)
# 如果字符串长度为0或1,直接返回n
if n == 0 or n == 1:
return n
# 接着讨论字符串长度大于1的情况
# 定义临时子字符串与子字符串储存列表
sub_s, res = '', []
# 开始遍历字符串s
for i in range(n):
# 判断如果当前字符s[i]不在子字符串
# sub_s中, 便把当前字符s[i]添加到sub_s中
if s[i] not in sub_s:
sub_s = sub_s + s[i]
# 此处多加一个判断, 当遍历到s最后一个元素
#仍无重复字符, 将该子字符串添加到子字符串res中
if i == n - 1:
res.append(sub_s)
# 当前字符s[i]已存在于子字符串sub_s中
else:
# 先将当前子字符串sub_s存入res
res.append(sub_s)
# 在sub_s中找到与s[i]相同元素的索引
ind = sub_s.index(s[i])
# 取sub_s中相同元素之后的部分, 便去掉了重复元素
sub_s = sub_s[(ind+1):]
# 添加当前元素,继续遍历循环, 直到最后一元素
sub_s = sub_s + s[i]
# print(res)
# 找到无重复元素的最长子字符串, 并返回其长度
length = 0
for i in res:
len_i = len(i)
if len_i > length:
length = len_i
return length
运行结果
我们看到时间复杂度还是可以的,但是空间复杂度较大,是因为使用了存储所有子串的res列表。所以可以进一步优化,不用res存储所有的子串,在遍历的时候直接比较字串长度去最长的那个,这样时间上可以进一步优化,空间复杂度还会降下来。