题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
一开始我的想法是用list集合做,结果虽然很省空间但是用时过长
这是一开始的代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
int max = 1;
if (s.equals("")) {
max = 0;
} else {
List list = new ArrayList();
int length[] = new int[s.length()];//list集合长度,元素在循环中添加,寻找出最长的
for (int i = 0; i < length.length; i++) {
length[i] = 1;
}
for (int j = 0; j < length.length-1; j++) {
list.add(s.charAt(j));
for (int i = j+1; i < s.length(); i++) {
if (!list.contains(s.charAt(i))) {
list.add(s.charAt(i));
length[j]++;
} else {
list.clear();
break;
}
}
}
max = length[0];
for (int i = 1; i < length.length-1; i++) {
if (max < length[i]) {
max = length[i];
}
}
后来看了大佬们的解析以后才发现自己好傻.....
这是改进后的代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character,Integer> map = new HashMap();
int ans = 0;//最大值
int left = 0;//左指针
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
left = Math.max(left, map.get(s.charAt(i)) + 1);
}
//无论是否相等我们都要录入下一个数的值和位置
map.put(s.charAt(i), i);
ans = Math.max(ans, i - left + 1);
}
return ans;
}
}
首先我们定义了一个left值它被认为是左边界,我们的每一次计算字符串字串长度都是从它指向的位置开始(即后面的 i-left+1)
每次录入之前我们先判断HashMap中是否存在该元素
(1)如果不存在的话,我们直接把这个元素和它在字符串中的位置录入进去,以pwwkew为例,p录入进去时,也把它的位置0录入了进去,第一个w录入进去是,它的位置1也被录入进去,随后我们就重新计算字串的长度,i-left代表它们之间的距离,再+1就是字串的长度了,
至于如果不理解为什么用max方法,我们下文会讲到
(2)如果存在的话,那么我们就应该先找到HashMap中存在的这个元素的位置,还是以pwwkew为例 当我们要录入第二个w时,我们发现map中已经存在w元素了,所以我们通过get方法来找到第一个w的位置,也就是1,
这个时候我们再让这个数+1,把它赋给left指针
如图所示
原来left指向0位置,现在它变成了1+1 ==2的位置,然后我们要做的事情是,把w这个元素再次记录到map中(其实也就是相当于刷新了它最后一次出现的位置),到这里第一个无重复元素的字串的长度记录工作结束,这时我们得到了长度ans==2
接下来就是记录第二个字串的长度,与上面相同的操作,我们每一次都做判断是否存在,录入map,以及计算字串长度的操作
(现在我们就可以知道为什么要用max方法了,因为第二个字串的初始长度可能是小于上一个字串的长度的,所以我们要去最大的那个长度),直到i==5也就是第三个w的时候,在这之前ans==4-2+1 ==3,
然后我们根据map.get()方法判断上一次w出现的位置,也就是2,所以现在left指向了2+1==3也就是k,我们将w录入也就是刷新它的最后一次出现的位置,然后计算字串的长度,5-3+1 == 3。
所以最大长度ans就是3
还有一个需要注意的点就是
left = Math.max(left, map.get(s.charAt(i)) + 1);
千万不要觉得max没用就写成 left = map.get(s.charAt(i))+1;
像abba这种情况,当我们录入第二个b的时候 left就会等于 1+1 ==2,但是后面又出现了一个a,这个时候如果是这种形式的话,left就会变成0+1 == 1也就相当于left左移了,这个时候的字串就变成了bba了
所以我们一定要取它的max值