Q:给定一个字符出,输出其不包含重复字符的最长子串的长度
注意:
1.子串是可以包括自身;
2.substring(0, 1)等价于charAt(0);
3.空字符串也算;
# 典型试错字符串
1: " ", " "
2: "au", "aab", "abba"
3: "pwwkew", "dvdf", "aabaab!bb"
4: "jbpnbwwd"
5: "tmmzuxt"
6: "gsqygebs", "bbtablud", "ggububgvfk"
7: "yfsrsrpzuya"
10: "nigzhtkqxr", "aleiivuuxszpaqojv"
S1-1:
- 从左向右依次截取一个字符c;
- 判断c是否包含于字符串s中(s由之前连续截取的不重复字符组成);
- 不包含就将c与追加到s;
- 包含就将s中c重复的那个字符及其之前的字符全部去掉,再将c追加到s;
- 输出s的最大长度值
class Solution {
public int lengthOfLongestSubstring(String s) {
//字符串的长度
int l = s.length();
//及时止损
if(l==0||l==1){
return l;
}
//最长不重复子串长度
int len=1;
//存储不重复子串长度的集合
StringBuilder sb=new StringBuilder();
//初始化
sb.append(s.charAt(0));
//从左开始依次截取,第一次截取第二个字符
for (int i = 1; i < l; i++) {
//获取字符
String ch = String.valueOf(s.charAt(i));
//获取重复下标
int index = sb.indexOf(ch);
//判断是否重复
if(index >= 0){
//重复---字符串去掉重复部分
sb.delete(0,index+1);
}
//追加字符
sb.append(ch);
//存储不重复子串的长度
if(sb.length()>len){
len=sb.length();
}
}
return len;
}
}
S1-2:空间优化
由提交结果可知,S1-1的内存消耗较大,原因在于每次获取字符需要将其转化为字符串,那么可不可以直接使用字符?如果直接使用字符,就不能使用StringBuilder,Stirngbuilder存储的是不重复的字符串,方便校验重复字符和计算最长子串,如果不使用StringBuilder,那么就需要将这俩个功能拆开,可以使用Map来校验重复字符(key唯一),引进一个临时变量来计算最长字串(用来存储不重复子串的开始下标)
- 从左向右依次截取一个字符c;
- 判断c是否包含于map中;
- 包含就比较新下标值和临时值的大小,然后将最大值赋值给临时值;
- 将c与c的下标存入m;
- 计算不重复子串的最长长度(取上一次计算的最长长度和当前遍历到的下标值-临时值的最大值);
public int lengthOfLongestSubstring(String s) {
//获取字符串长度
int l = s.length();
//预设最长不重复子串长度
int len=0;
//构建用于校验重复字符的map
Map<Character,Integer> map = new HashMap<>();
//遍历字符串
for(int i=0,j=-1;i<l;i++){
//获取字符
char c=s.charAt(i);
//判断是否重复
if(map.containsKey(c)){
//重复则更新最长不重复子串的起始值
j=Math.max(j,map.get(c));
}
//更新map
map.put(c,i);
//计算不重复子串的最长长度
len=Math.max(len,i-j);
}
return len;
}