leetCode3:无重复字符的最长子串
程序员文章站
2022-04-04 09:59:37
...
问题理解:
该问题,变量是一个字符串,让我们找出字符串中没有重复字符的最长的子字符串,并返回该子字符串的长度。首先,我想
到的就是遍历字符串,我们先定义一个字符串存储我们校验过的非重复的字符串,然后每次遍历都判断字符有没有跟之前的字符重复,
如果有重复,找出重复的位置,然后从重复的位置开始向后校验,之前的重复的去掉。
接下来我就把我的解题历程,以及犯得错误,如果不想看的话,直接翻到最后。
public static int lengthOfLongestSubstring(String s) {
char[] chars = s.toCharArray();
if (chars.length == 0){ // 为空,直接返回
return 0;
}
String tmp = ""+chars[0];
int res =1;
for (int i = 1; i < chars.length; i++) {
int index = tmp.indexOf(chars[i]+""); // 有重复就返回重复角标,没有返回-1
if (index ==-1){
tmp +=chars[i]+"";
}else {
res = res>tmp.length()?res:tmp.length(); // 判断之前的没有重复的子字符串跟现在相比那个长
tmp = tmp.substring(index); // 从重复的位置开始截取
}
}
return res>tmp.length()?res:tmp.length();
}
一般情况下是可以的,直到我的代码遇到了这个字符串:"aabaab!bb",预期结果是3,我的是2,我debug了下,发现
是我对substring这个方法使用错了,前两个都是a,然后我遍历时找到同第二个a相同的角标为0,然后使用substring(0),
是截取不到的,然后也忘记把后面的那个字符加上了,改动如下:
tmp = tmp.substring(index+1)+chars[i]; // 从重复的位置后面那位开始截取,加上遍历到的字符。
这样运行就成功了,但是 效率 很低,给大家看下。
现在要看下题解了,哈哈,自己的思路效率有点低。看完题解感觉 思路是一样的,不过他的代码感觉更简洁,而
且使用的空间应该比我小,我感觉他的精髓就是i = Math.max(map.get(s.charAt(j)),i);这个地方获取之前已经放入map里
面重复的字符的角标赋值给i。
public static int lengthOfLongestSubstring2(String s) {
int n = s.length(),ans = 0;
Map<Character, Integer> map = new HashMap<>(n);
for(int i=0,j=0;j<n && ans < n-i;j++){
if (map.containsKey(s.charAt(j))){
i = Math.max(map.get(s.charAt(j)),i);
}
ans = Math.max(ans,j-i+1);
map.put(s.charAt(j),j+1);
}
return ans;
}
我感觉自己能写出来,不过代码优点复杂,不如官方的解法简洁,不过比他的好理解一点吧。
上一篇: LeetCode3 无重复字符的最长子串