原题: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" 是一个子序列,不是子串。
题解
滑动窗口
基本原理是保证窗口(子串)中的字母均唯一。为此需要两个指针来分别构成窗口的左边界与右边界,当未遇到重复字母时,调整右边界;当遇到重复字母时,调整左边界,以输入s="aca"为例
1.为完成上述操作,除了创建两个分别代表窗口左右边界的左指针(l)和右指针(r)以外,还需构建一个以字母ASCII码为索引,以其后继字母在字符串s中的下标为值的储存序列c并将其初始化为0,以及一个用于返回最终结果的变量res。使用循环不断将右指针向右遍历;
2.每次循环开始,以右指针向的字母的ASCII码为索引访问储存序列c(c[s[j]]),比较所得值和左指针的大小并将左指针更新为两者间的较大者(max(l,c[s[r]]))。若左指针发生改变,意味则该字母再次出现,因为只有当字母再次出现时,才有可能访问储存序列中的同一索引
3.此后,以右指针向的字母的ASCII码为索引,以其后继字母在字符串s中的下标为值,将该字母放入储存序列c(c[s[j]]=r+1)并根据此时左右指针的位置更新结果变量res(res=max(res,j-i+1))
4.重复步骤2、3,直至右指针完成遍历,返回结果变量res
代码实现
C++
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> c(128,0);
int res=0;
int l=0;
for (int r=0;r<s.size();r++) {
l=max(l,c[s[r]]);
c[s[r]]=r+1;
res=max(res,r-l+1);
}
return res;
}
};
C#
public class Solution {
public int LengthOfLongestSubstring(string s) {
int[] c=new int[128];
Array.Clear(c,0,c.Length);
int res=0;
int l=0;
for(int r=0;r<s.Length;r++){
l=Math.Max(l,c[s[r]]);
c[s[r]]=r+1;
res=Math.Max(res,r-l+1);
}
return res;
}
}