问题描述 :
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例:
示例 1:
输入: “abcabcbb”
输出: 3
解释: 无重复字符的最长子串是 “abc”,其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 无重复字符的最长子串是 “b”,其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 无重复字符的最长子串是 “wke”,其长度为 3。
请注意,答案必须是一个子串,”pwke” 是一个子序列 而不是子串。
示例 3:
输入: “adeafgdc”
输出: 6
解释: 无重复字符的最长子串是 “eafgdc”,其长度为 6。
思路:
滑动窗口法:
滑动窗口法描述:滑动窗口算法是用一个窗口去满足问题的约束条件。一旦违反约束条件,窗口就会变得不稳定,这种不稳定需要通过增加或减少窗口的大小来消除。
在这道题目中,约束条件为子串中的字母不重复。首先,我们构建一个窗口(空数组),用来保存不重复的子串。并用max_len来保存最大窗口长度。然后遍历整个字符串,如果当前值不在窗口中,我们就把它加入其中,这样窗口的长度就增加了1。接着向后遍历字符串,一旦发现当前值已经存在于窗口中,此时约束条件不满足。我们比较当前窗口的长度与之前记录的长度max_len的大小,记录下较大者。为了再次满足约束条件,我们从窗口的最左边开始去除窗口中的元素,直到与当前值相同的元素被去除为止。接着向后遍历数组,直至结束。最后,若最后一个元素不在窗口中,那么我们会将它加入到窗口中, 所以此时应该取之前记录值max_len与当前窗口长度较大者。
第四例图解说明:
# -*- coding:utf-8 -*-
# Python Interpreter: Python 2.7.2
# Function: 求解给定字符串中不含重复字符的最长子串的长度
# Author: Qiankun Wang
# Data: 2018.9.13
class Solution(object):
def lengthOfLongestSubstring(self,s):
n = len(s)
# 窗口的右边界
right = 0
window = []
# 记录窗口的长度
max_len = 0
# 如果当前字母不在窗口中,即不存在重复字母,把当前字母加入到窗口中
while right < n:
if s[right] not in window:
window.append(s[right])
# 若当前字母已经在窗口中,更新窗口的长度。
else:
if len(window) > max_len:
max_len = len(window)
# 去除窗口左边的字母,直到不含重复元素为止
#(即不含有与当前值重复的字母)。
while s[right] in window:
window.pop(0)
window.append(s[right])
# 继续向右边访问字符串
right += 1
# 当访问到字符串最后时,若最后一个元素不在窗口中,那么我们会
#将它加入到窗口中,所以此时应该取之前记录值与当前窗口长度较大者。
return max(max_len,len(window))
if __name__ == "__main__":
# s = raw_input().strip('"')
s1 = "abcabcbb"
s2 = "bbbbb"
s3 = "pwwkew"
s4 = "adeafgdc"
solu = Solution()
# print solu.lengthOfLongestSubstring(s)
print solu.lengthOfLongestSubstring(s1)
print solu.lengthOfLongestSubstring(s2)
print solu.lengthOfLongestSubstring(s3)
print solu.lengthOfLongestSubstring(s4)
参考:
https://blog.csdn.net/ahaha__123/article/details/80284445 图解部分
http://www.techiedelight.com/sliding-window-problems/ 滑动窗口算法
https://www.cnblogs.com/Kobe10/p/6360993.html 哈希表解法