描述:给定一个字符串s,请你找出其中不含有重复字符的 最长子串 的长度。
难度:中等题。
我的思路是:类似于局部最优的思想吧。把字符串遍历一遍,找到开头到遍历过程中的最长不重复子串长度,最后得到的就是结果。
思想是:首先new一个HashMap,key是遍历过程中的字符,val是在字符串中的下标。
为了简化思想,构建三个变量:
res,最终的长度;
tmpRes,遍历过程中目前包括当前字符的不重复子串长度;
flag,包括当前遍历节点的不重复子串的起始位置(这个可以不设,通过计算得到)。
当遍历到下标为x的位置时,若此字符在map中有这个key,且其对应val(上次出现该字符的下标)大于flag(即目前包括最后节点在内的不重复子串中有这个字符)。则flag++(当前包括最后节点的不重复子串起点后移),把新的val也put进map覆盖掉旧的。同时判断tmpRes是否大于res,若大则res = tmpRes。(上个不重复子串终止了,看看是否比之前最长的长度大)。tmpRes也要改为当前新的包括最后一个下标的不重复子串的长度。若条件不成立,很简单,当前子串还是不重复子串,继续tmpRes++。
下面是代码:
public static int lengthOfLongestSubstring(String s) {
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
int length = s.length();
int res = 0;//最终的长度
int tmpRes = 0;//当前字符串下的不重复长度
int flag = 0;//不重复子串开始的下标
for(int i = 0; i < length; ++i){
if(map.containsKey((int)s.charAt(i)) && map.get((int)s.charAt(i)) >= flag){
flag = map.get((int)s.charAt(i)) + 1;
if(tmpRes > res){
res = tmpRes;
}
tmpRes = i - flag + 1;
}else {
tmpRes++;
}
map.put((int)s.charAt(i), i);
}
return res > tmpRes ? res : tmpRes;
}
最后return的判断是针对该字符串全部不重复,这样过程中是没给res赋值的。