暴力求解
class solution(object):
def findMaxLength(self, s):
n = len(s)
max_length = 0
for i in range(n):
# set 是 Python 中的一种集合数据类型。集合是无序且不重复的元素的集合
char_set = set()
for j in range(i, n):
if s[j] in char_set:
break
char_set.add(s[j])
max_length = max(max_length, j - i + 1)
return max_length
set 是 Python 中的一种集合数据类型。集合是无序且不重复的元素的集合
j - i + 1: 这部分计算的是当前子串的长度。j是当前子串的结束位置,i是当前子串的起始位置,所以j - i计算的是子串的长度。+ 1是因为我们要考虑子串的最后一个字符。max_length: 这是之前已经计算过的不含重复字符的最长子串的长度。max(max_length, j - i + 1): 这是一个取最大值的操作。它比较当前计算得到的子串长度和之前已知的最大长度,然后选择较大的那个作为新的最大长度。
该算法的时间复杂度是 O(n^2)
滑动窗口
max_len = 0
char_set = set()
n = len(s)
# 定义窗口的首尾端 (start, end),然后滑动窗口
start = 0
for end in range(n):
# 如果当前字符已经在集合中,需要移动窗口的左指针
while s[end] in char_set:
char_set.remove(s[start])
start += 1
# 将当前字符加入集合
char_set.add(s[end])
# 更新最大长度
max_len = max(max_len, end - start + 1)
# 返回答案 (最大长度)
return max_len
测试
sol = Solution()
input_str = "abbc"
result = sol.lengthOfLongestSubstring(input_str)
print(result)
-
右指针
rk和左指针i:rk是右指针,用于扩展当前考虑的无重复字符子串的右边界。i是左指针,用于收缩当前考虑的无重复字符子串的左边界。
-
循环遍历字符串:
- 外层循环由
for i in range(n)组成,其中i是左指针。 - 内层循环由
while rk + 1 < n and s[rk + 1] not in occ组成,其中rk是右指针。 - 在每次外层循环中,首先将左指针向右移动一格(移除一个字符),然后不断地将右指针向右移动,直到出现重复字符或者达到字符串末尾。
- 外层循环由
-
更新最大长度
ans:- 在内层循环中,通过
ans = max(ans, rk - i + 1)更新最大长度,确保ans始终存储的是当前找到的最长无重复字符子串的长度。
- 在内层循环中,通过
模板解法
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# Step 1: 定义需要维护的变量, 本题求最大长度,所以需要定义max_len, 该题又涉及去重,因此还需要一个哈希表
max_len, hashmap = 0, {}
# Step 2: 定义窗口的首尾端 (start, end), 然后滑动窗口
start = 0
for end in range(len(s)):
# Step 3
# 更新需要维护的变量 (max_len, hashmap)
# i.e. 把窗口末端元素加入哈希表,使其频率加1,并且更新最大长度
# 尝试从哈希表中获取当前字符在哈希表中的值,如果哈希表中没有这个字符,则返回默认值0
hashmap[s[end]] = hashmap.get(s[end], 0) + 1
if len(hashmap) == end - start + 1:
max_len = max(max_len, end - start + 1)
# Step 4:
# 根据题意, 题目的窗口长度可变: 这个时候一般涉及到窗口是否合法的问题
# 这时要用一个while去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法
# 当窗口长度大于哈希表长度时候 (说明存在重复元素),窗口不合法
# 所以需要不断移动窗口左指针直到窗口再次合法, 同时提前更新需要维护的变量 (hashmap)
while end - start + 1 > len(hashmap):
head = s[start]
hashmap[head] -= 1
if hashmap[head] == 0:
del hashmap[head]
start += 1
# Step 5: 返回答案 (最大长度)
return max_len
sol = Solution()
input_str = "abbc"
result = sol.lengthOfLongestSubstring(input_str)
print(result)
动态演示1
模板解法