最长无重复子串

91 阅读2分钟

力扣第3题 最长无重复子串

[无重复字符的最长子串](leetcode.cn/problems/lo…)

题目描述

给定一个字符串 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 由英文字母、数字、符号和空格组成

二、滑动窗口解决

abcabcbb 为例: 首先使用尾指针去遍历字符串。维护一个map,。如果当前字符出现过,且出现的位置大于起始位置,更新起始位置。

  1. 维护一个最大的长度max
  2. 维护一个map , 存的结构为 map.set(str[j],j),用于记录当前遍历到的字符最近一次出现的位置.
  3. 维护两颗指针 i,j , i为头指针,j 为尾指针。
  4. 如果当前字符出现过,且出现的位置大于起始位置,更新起始位置为出现当前字符的位置+1
  5. 不管是否出现,更新map.
  6. max 和 滑动窗口比较,取最大值。

三、题解

function maxLenNoRepeat(str) {
	let max = 0;
	let map = new Map();
	for (let i = 0, j = 0; j < str.length; j++) {
		// 视图取map 中对应的字符上一次出现的下标,如果上次出现的下标存在且在start指针的后面,就需要更新start的指针。
		if (map.has(str[j]) && map.get(str[j]) >= i) {
			// 如果能取出来,说明可能需要更新左指针
			i = map.get(str[j]) + 1;
		}
		// 不管有没有取出来,更新map
		map.set(str[j], j);
		max = Math.max(max, j - i + 1);
	}
	return max;
}