LeetCode第三题:无重复字符的最长字串
给定一个字符串s,请你找出其中不含有重复字符的最长字串的长度
示例:
输入:s = "abcabcbb"
输出:3
解释:因为无重复字符的最大字串是"abc",所以其长度为3
解法1:
根据窗口滑动的特点,可以像下面这种方式递归的取重复
第一次:
abcabcbb
a
ab
abc
第二次:
abcabcbb
b
bc
bca
第三次:
abcabcbb
c
ca
cab
第四次:
abcabcbb
a
ab
abc
第五次:
abcabcbb
b
bc
第六次:
abcabcbb
c
cb
第七次:
abcabcbb
b
这样遍历之后就可以得出结果最长无重复子串为3
public int subStr(String str){
//得到str的长度,从第一个开始,遍历比较
int len = str.length();
// 比较的指针
int i = 1;
// 开始的指针
int j = 0;
int max = 1;
while(i < len){
boolean isContain = str.substring(j, i).contains(String.valueOf(str.charAt(i)));
// 当前的字符串内是否包含下一个字符,如果包含,则移动指针
if(isContain){
max = Math.max(max,i-j);
j = j + 1;
i = j;
}
// 否则只将i指针下移
i++;
}
max = Math.max(max, i-j);
return max;
}
解法2:
上面的解法虽然可以得到结果,但是在计算的过程中存在着一定的重复遍历,比如对于一个字符串"pwcwdev",在遍历到第二个w的时候,能得到两个w之间只有两个无重复字串,然后根据上面的解法,还要指针下移到w,然后遍历一遍,等到了第二个w才算停止,得到了此次遍历的子串是2,就造成了重复遍历,具体如下如所示
所以我们就可以声明一个map结构存储,其中map的key就是字符,value就代表该字符不重复的位置,为字符位置+1,通过这种方式减少时间复杂度。具体过程如下所示
public int subString2(String s){
// 最大无重复字串长度
int max = 0;
// 从零开始
int start = 0;
Map<Character, Integer> map = new HashMap<>();
for (int end = 0; end < s.length() ; end++) {
// 遍历的字符是否已经在map中
if (map.containsKey(s.charAt(end))){
// 在的话更新start位置
start = Math.max(map.get(s.charAt(end)), start);
}
max = Math.max(max, end - start + 1);
// 将其放到map中
map.put(s.charAt(end), end + 1);
}
return max;
}
测试代码
public static void main(String[] args) {
LeetCode03 lc = new LeetCode03();
System.out.println(lc.subStr("abcadef"));
System.out.println(lc.subString2("abcadef"));
}