题目:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
问题
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是"abc",所以其长度为3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是"b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
思路
本题是找出最大长度的子串,而不是子序列。我们可以用双重循环进行逐个比较,外层循环用j表示需要比较的第j个字符,内层循环用k表示,比较的字符将在前j个字符中比较,当前j个字符和s[j]均不相等时,说明s[j]可加入到无重复子串中,j++,比较下一个字符;
当存在s[k]==s[j]的情况下,说明无重复字符的条件不满足,此时将得到的最长子串长度记录到max中;
那么,无重复字符的条件被打破后,k的值怎么变化呢,我们来用图中的例子来说明,如"abcadcbb",当k=0,j=3时,s[k]==s[j],此时,s[0]字符是不再需要比较了的,下次比较的位置可以从k=1开始,无需再从k=0开始,否则会陷入循环,那么我们需要用一个变量i来记录每次匹配到重复字符时k的位置的下一个位置i=k+1,s[i]便是下次字符比较的起始位置。
代码
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int max=0,i=0;
int len=s.size();
for(int j=0;j<len;j++)
{
//在前j个字符中比较
for(int k=i;k<j;k++)
{
if(s[k]==s[j])
{
i=k+1; //字符重复时,记录重复字符位置的下一个位置,即下次比较字符的起始位置
break;
}
}
if(j-i+1 > max) max = j-i+1;
}
return max;
}
};