LeetCode3.无重复字符的最长子串
难度:中等
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
双指针
思路;
- 第一种情况,s只有一个元素或者空子串;
- 设置双指针left、right,一个指向最左端,一个指向下一个元素;
- right向右移动cnt记录不重复字串长度;
- right向右移动,直到right指向的元素在s[left:right]中存在,找到改元素在窗口中的位置,并将left指向该元素的下一个元素;
- 然后比较cnt 与 right - left的大小;
- 如果下一个元素不在s[left:right]中,则right加1;
- 最后要考虑如果最大子串在最后,再做一次比较;
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
if len(s) < 2:
return len(s)
left, right = 0, 1
cnt = 1
while right < len(s):
if s[right] in s[left:right]:
left += s[left:right].index(s[right]) + 1
cnt = max(cnt,right-left)
else:
right += 1
cnt = max(cnt,right-left)
return cnt
字典(哈希表)与双指针
- 创建字典,将字符为键,索引为值保存到字典中;
- i为左指针,j为右指针;
- 然后遍历字符串,如果s[j]在字典中,则取值最大的那个;
- 然后比较ans 和j-i+1,保存最大子串长度;
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
st = {}
i, ans = 0, 0
for j in range(len(s)):
if s[j] in st:
i = max(st[s[j]], i)
ans = max(ans, j - i + 1)
st[s[j]] = j + 1
return ans
状态规划
- 初始化,dp[0] = s[0];
- s[i]不在dp[i-1]中,此时dp[i] = dp[i - 1] + s[i];
- s[i]在dp[i-1]中,要将s[i]从dp[i-1]中去除,从左往右依次去除元素,直到去除s[i],dp[i]=(dp[i-1] - dp[0:index(s[i])+1)]) + s[i];
- 最后取出最大的len(dp[i]);
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
if not s:
return 0
n = len(s)
dp = [0] * n
dp[0] = s[0]
for i in range(1,n):
if s[i] not in dp[i-1]:
dp[i] = dp[i-1] + s[i]
else:
tem = dp[i-1].index(s[i])
dp[i] = dp[i-1][tem+1:] + s[i]
ans = 1
for i in range(n):
ans = max(ans, len(dp[i]))
return ans