一、题目描述
二、解题思路
本题最小白的思路就是用双指针,取出子串后对子串判断是否含有重复的字符,如果没有重复字符则更新满足条件的最大子串长度。
但是这样做的话时间复杂度非常高,达到了O(n³),超出了题目的最长执行时间。所以要对双指针移动的这一过程进行优化,尽量排除掉肯定不满足条件(含有相同字符)的子串。
这里左右指针移动过程中,右指针的每次移动并不需要让左指针从头再开始遍历。
举个例子:
字符串: a b c a c c d b
下标: 0 1 2 3 4 5 6 7
这里使用nowsubstr = substring(left,right),是个左闭右开区间,nowstr是当前子串
需要检查当前子串是否包含chatAt(right),如果不包含,则说明可以把right++,扩大子串规模
right= 0 left= 0 子串 "" 子串和charAt(right)对比没有重复字符 right++
right= 1 left= 0 子串 a 子串和charAt(right)对比没有重复字符 right++
right= 2 left= 0 子串 ab 子串和charAt(right)对比没有重复字符 right++
right= 3 left= 0 子串 abc 子串和charAt(right)对比有重复字符 a 则代表如果以charAt(right)为最右侧字符时,需要更新left,直到新的substring(left,right)中没有chatAt(right)。这里可以看到left=1就满足了要求,新的子串为 bc。 然后 right++
right= 4 left= 1 子串 bca 子串和charAt(right)对比有重复字符 c 则代表如果以charAt(right)为最右侧字符时,需要更新left,直到新的substring(left,right)中没有chatAt(right)。这里可以看到left=3就满足了要求,新的子串为 a。 然后 right++
...
上述过程我们可以看到,因为在之前的比较中,substring(left,right)已经是以right-1位置字符作为最右侧的满足题目条件的子串(不重复字符),我们的left不需要从0再开始分析字符是否重复了【这一点是和题目要求紧密相关的】。
三、代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return int整型
*/
public int lengthOfLongestSubstring (String s) {
int maxLength=0;
int left=0,right=0;
System.out.println(s.length());
for(;right<s.length();right++){
for(;left<=right;left++){
String substr=s.substring(left,right);
if(!substr.contains(s.charAt(right)+"")){
//left到right没有重复字符
break;
}
}
int diff=right+1-left;
maxLength=maxLength>diff?maxLength:diff;
}
return maxLength;
}
}