LeetCode 03 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。请注意,你的答案必须是 子串 的长度,”pwke” 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
第一种解法:暴力循环
遍历字符串中的每一个字符,然后把已有的字符放到一个 set 中,直到出现 set 中重复的字符,记录下此时的子串的长度,最后得到最大的子串长度就是结果。但是这种算法的复杂度是O(n^2)。
第二种解法:滑动窗口
有两个指针start和end,end随着遍历字符串慢慢增大,再创建一个用于存放字符的Map,Map的Key就是对应的字符,Value存放的是字符出现的位置+1,意为从这个位置开始到最近出现相同字符的这一串字符是不重复的。这样每次的子串长度就是 end - start + 1,最后比较出一个最大的子串长度就是结果。这种算法的复杂度是O(n)。
var lengthOfLongestSubstring = function(s) { |
状态演示
示例1: “abcabcbb”
当前字符为”a”,Map中没有该字符,更新Map { “a” : 1 } ,start为0,end为0,当前子串长度1,最长子串长度1,当前子串为”a”
当前字符为”b”,Map中没有该字符,更新Map { “a” : 1, “b”: 2 } ,start为0,end为1,当前子串长度2,最长子串长度2,当前子串为”ab”
当前字符为”c”,Map中没有该字符,更新Map { “a” : 1, “b”: 2, “c”: 3 } ,start为0,end为2,当前子串长度3,最长子串长度3,当前子串为”abc”
当前字符为”a”,Map中有该字符,更新Map { “a” : 4, “b”: 2, “c”: 3 } ,start为1,end为3,当前子串长度3,最长子串长度3,当前子串为”bca”
当前字符为”b”,Map中有该字符,更新Map { “a” : 4, “b”: 5, “c”: 3 } ,start为2,end为4,当前子串长度3,最长子串长度3,当前子串为”cab”
当前字符为”c”,Map中有该字符,更新Map { “a” : 4, “b”: 5, “c”: 6 } ,start为3,end为5,当前子串长度3,最长子串长度3,当前子串为”abc”
当前字符为”b”,Map中有该字符,更新Map { “a” : 4, “b”: 7, “c”: 6 } ,start为5,end为6,当前子串长度2,最长子串长度3,当前子串为”cb”
当前字符为”b”,Map中有该字符,更新Map { “a” : 4, “b”: 8, “c”: 6 } ,start为7,end为7,当前子串长度1,最长子串长度3,当前子串为”b”
示例2:”pwwkew”
当前字符为”p”,Map中没有该字符,更新Map { “p” : 1 } ,start为0,end为0,当前子串长度1,最长子串长度1,当前子串为”p”
当前字符为”w”,Map中没有该字符,更新Map { “p” : 1, “w”: 2 } ,start为0,end为1,当前子串长度2,最长子串长度2,当前子串为”pw”
当前字符为”w”,Map中有该字符,更新Map { “p” : 1, “w”: 3 } ,start为2,end为2,当前子串长度1,最长子串长度2,当前子串为”w”
当前字符为”k”,Map中没有该字符,更新Map { “p” : 1, “w”: 3, “k”: 4 } ,start为2,end为3,当前子串长度2,最长子串长度2,当前子串为”wk”
当前字符为”e”,Map中没有该字符,更新Map { “p” : 1, “w”: 3, “k”: 4, “e”: 5 } ,start为2,end为4,当前子串长度3,最长子串长度3,当前子串为”wke”
当前字符为”w”,Map中有该字符,更新Map { “p” : 1, “w”: 6, “k”: 4, “e”: 5 } ,start为3,end为5,当前子串长度3,最长子串长度3,当前子串为”kew”