描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
代码及注释
我的解法 执行时间击败100%
public static int lengthOfLongestSubstring(String s) {
//转化为数组
char[] chars = s.toCharArray();
int charLength = chars.length;
int i = 0, j = 0, n = 0, len = 0, maxLen = 0;
if (charLength <= 1) {
return charLength;
}
//标志 用于判断遍历到的字符是否出现重复
boolean tag = false;
while (i < charLength && j + 1 < charLength) {
n = j + 1;
tag =false
for (int k = i; k < n; k++) {
//如果数组里已经有该字符 修改ij指针
if (chars[n] == chars[k]) {
len = j - i + 1;
tag = true;
//修改最大长度
maxLen = maxLen > len ? maxLen : len;
i = k + 1;
j++;
break;
}
}
if (!tag) {
j++;
//这是判断特殊 比如 au 就会导致maxLen 无法修改
if(j == charLength-1){
len = j - i + 1;
//修改最大长度
maxLen = maxLen > len ? maxLen : len;
}
}
}
return maxLen;
}
官方解法 时间复杂度O(n)
//官方题解 滑动窗口 可以解决一类问题
/*思路:
这道题主要用到思路是:滑动窗口
什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
如何移动?
我们只要把队列的左边的元素移出就行了,直到满足题目要求!
一直维持这样的队列,找出队列出现最长的长度时候,求出解!
时间复杂度:O(n)O(n)O(n)
* */
public static int lengthOfLongestSubstring2(String s) {
if (s.length() == 0) return 0;
//用哈希表 存储 已经遍历的字符 查找效率更高0(1)
// 我解题时也有想过,奈何感觉不会写,这里查找效率应该比我遍历查找快我的应该是(n)
//但是实际跑起来比我的慢 我认为是用封装类 和 map 运行比较慢
HashMap<Character, Integer> map = new HashMap<>();
int max = 0;
int left = 0;
for (int i = 0; i <s.length(); i++) {
if (map.containsKey(s.charAt(i))){
//这里需要比较一个最大值 是因为 哈新表存的是遍历过得所有值
//比如字符串为abacdeb left 目前指向第二个a 查到哈希表中存在b是第一个b这是时候left就不能改变
left = Math.max(left,map.get(s.charAt(i))+1);
}
map.put(s.charAt(i),i);
max = Math.max(max, i-left+1);
}
return max;
}