力扣算法:无重复字符的最长子串
一、无重复字符的最长子串
1、问题
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
示例 4:
输入: s = “”
输出: 0
提示:
- 0 <= s.length <= 5 * 104
- s 由英文字母、数字、符号和空格组成
2、思路
- 创建一个字典map,用来存储“字符”及“字符位置下标+1”(加 1 表示从字符位置后一个才开始不重复)。
- 定义不重复子串的开始位置为 start,结束位置为 end,初始化为 0。
- 定义一个变量 ans,用来记录“无重复字符子串”的长度。
- 遍历字符串 s , 遍历结束条件为 end < 字符串长度 。
- 如果遍历到的字符在map中,此时将“该字符”作为 key 值,在map中获取其 value 值,与原start进行对比取最大值,并更新 start,更新后此时 [start, end] 区间内不存在重复字符。
- 无论是是否需要更新start,都需要将遍历到的字符添加到map中,并更新ans。
- 遍历结束返回ans。
3、代码
#coding:utf-8
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
start,end,ans,n,map= 0,0,0,len(s),{}
while end < n:
if s[end] in map:
start = max(map[s[end]],start)
map[s[end]] = end + 1
ans = max(end - start + 1, ans)
end += 1
return ans
if __name__ == "__main__":
# s = "abcabcbb"
# s = "bbbbb"
# s = "pwwkew"
# s = ""
# s = "dvdf"
s = "abba"
print(Solution().lengthOfLongestSubstring(s))
4、时间与空间复杂度
时间复杂度:O(n)
n为字符串长度
空间复杂度:O(∣Σ∣)
Σ表示字符集(即字符串中可以出现的字符),∣Σ∣ 表示字符集的大小
备注
1、问题来自:
力扣(LeetCode)
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
2、参考:
guanpengchn
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-jie-suan-fa-3-wu-zhong-fu-zi-fu-de-zui-chang-z/
版权声明:本文为weixin_43560913原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。