使用指针 - 滑动窗口优化 - 双指针法 - 使用数组索引,标记滑动窗口
说明:
直观的滑动窗口方法需要维护数组的增删,实际上比较耗时
使用双指针(索引),记录滑动窗口起始和结束的索引值,可以减除数组增删操作,提高效率
代码结构和上一种方法基本一致,只不过使用指针位移以及从原数组中截取,代替原来的窗口元素增删操作
效率:
Runtime: 40 ms, faster than 84.23% of Python online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 12.1 MB, less than 54.97% of Python online submissions for Longest Substring Without Repeating Characters.
复杂度分析:
时间复杂度:O(N)O(N)O(N)
空间复杂度:O(N)O(N)O(N)
代码:
class Solution4(object):
def lengthOfLongestSubstring(self, s: str) -> int:
# 字符串为空则返回零
if not s:
return 0
max_length = 0 # 滑动窗口数组
left, right = 0, 0 # 双指针
for i, c in enumerate(s):
# 如果字符不在滑动窗口中,则直接扩展窗口
if c not in s[left:right]:
# 右指针右移一位
right += 1
# 如果字符在滑动窗口中,则
# 1. 从窗口中移除重复字符及之前的字符串部分
# 2. 再扩展窗口
else:
# 在滑动窗口范围内中找出对应的首个字符的索引X,对应的新的左指针位置为X + 1
# 左指针右移 索引X增一 位
left += s[left:right].index(c) + 1
# 右指针右移一位
right += 1
# 更新最大长度
max_length = max(right - left, max_length)
# 如果最大长度不为零,返回最大长度
# 如果最大长度仍为零,则说明遍历整个字符串都没有发现重复字符,最大长度即为字符串本身的长度
#因为在程序中只执行了if的部分,所以max_length没有进行更新,右指针一直右移,直到字符串的最后。
#所以最大长度为0
return max_length if max_length != 0 else len(s)
需要注意的是最后一部分的解释,一定要理解。
参考程序连接地址:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/python-hua-dong-chuang-kou-xun-xu-jian-jin-de-3ge-/