无重复字符的最长子串
- https://leetcode.cn/problems/longest-substring-without-repeating-characters/
描述
- 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示
- 0 <= s.length <= 5 * 10410^4104
- s 由英文字母、数字、符号和空格组成
Typescript 版算法实现
1 )双指针滑动窗口遍历
function lengthOfLongestSubstring(s: string): number {
let l = 0;
let res = 0;
// 用于标记重复字符的字典结构
const map = new Map();
for(let r = 0; r < s.length; r++) {
if(map.has(s[r]) && map.get(s[r]) >= l) {
// 字典中存在
l = map.get(s[r]) + 1;
}
res = Math.max(res, r - l + 1);
map.set(s[r], r); // 字典更新最新的右指针
}
return res;
};
- 先找出所有不包含重复字符的子串,找出长度最大那个子串,返回其长度即可
- 用双指针维护一个滑动窗口,用来剪切子串
- 不断移动右指针,遇到重复字符,就把左指针移动到重复字符的下一位
- 在输入:“abcabcbb”
- 即左指针指向a(下标为0), 右指针指向c的时候,再移动一位, 右指针指向a(下标为3)的时候
- 左指针移动一位到b(下标为1)
- 移动过程中,记录所有窗口的长度,并返回最大值
2 )暴力遍历
function lengthOfLongestSubstring(s: string): number {
const len = s.length;
let max = 0;
for (let i = 0; i < len; i++) {
const set = new Set();
let maxLen = 0;
let j = i;
while (j < len && !set.has(s[j])) {
set.add(s[j]);
maxLen++;
j++;
}
max = Math.max(max, maxLen);
}
return max;
}
- 使用set集合来确定字符串的连续型,并暴力枚举各种符合情况
- 这种算法不推荐
Python3 版算法实现
1 ) 方案1
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
l = 0
res = 0
# 用于标记重复字符的字典结构
char_index_map = {}
for r in range(len(s)):
if s[r] in char_index_map and char_index_map[s[r]] >= l:
# 字典中存在
l = char_index_map[s[r]] + 1
res = max(res, r - l + 1)
char_index_map[s[r]] = r # 字典更新最新的右指针
return res
2 ) 方案2
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
len_s = len(s)
max_len = 0
for i in range(len_s):
char_set = set()
current_len = 0
j = i
while j < len_s and s[j] not in char_set:
char_set.add(s[j])
current_len += 1
j += 1
max_len = max(max_len, current_len)
return max_len
Golang 版算法实现
1 ) 方案1
func lengthOfLongestSubstring(input string) int {
l := 0
res := 0
// 用于标记重复字符的字典结构
charIndexMap := make(map[byte]int)
for r := 0; r < len(input); r++ {
if idx, ok := charIndexMap[input[r]]; ok && idx >= l {
// 字典中存在
l = idx + 1
}
res = max(res, r-l+1)
charIndexMap[input[r]] = r // 字典更新最新的右指针
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
2 ) 方案2
func lengthOfLongestSubstring(input string) int {
len := len(input)
max := 0
for i := 0; i < len; i++ {
charSet := make(map[byte]bool)
maxLen := 0
j := i
for j < len && !charSet[input[j]] {
charSet[input[j]] = true
maxLen++
j++
}
if maxLen > max {
max = maxLen
}
}
return max
}
757



被折叠的 条评论
为什么被折叠?



