常规的解法是:
比如一个字符串abcabcbb
每一次截取一段
abcabcbb->捕捉不重复串 = abc
bcabcbb->捕捉不重复串 = bca
cabcbb->...
abcbb->...
bcbb.->...
,,,
最后将所有不重复串填塞到一个表里面
获取这个表中最长串的长度返回:
/*
* @lc app=leetcode.cn id=3 lang=java
*
* [3] 无重复字符的最长子串
*/
// @lc code=start
class Solution {
public int lengthOfLongestSubstring(String s) {
// System.out.println("hello world");
if(s.length() == 0){
return 0;
}
char[] ca = s.toCharArray();
int len = 0;
int lastChar = ca[0];
List li = new ArrayList();
for(int i =0;i charArr = new ArrayList();
}
}
// @lc code=end
效率感人:
我搜索了一下别人优秀的解法,然后,他们的角度及其刁钻,我写一下解题思路:
比如ababvd
1.动态的获取start的位置
2.长度等于当前遍历索引index - start +1(从0开始算起索引索引添加1)
当start = 0时
index = 0时,子串长度(sl)为1
index = 1时,子串长度为2
index = 2时,这个时候,我们观测到子串结构为aba,显然是一个重复子串,所以,start就应该变了应该拒绝掉上一个重复字符的位置,也就是start = 1,子串编程ba
index = 3时,子串为bab,显示是一个重复子串,start应该往前走一步为ab,sl = 2
index = 4时,子串为abv,sl = 3
index = 5时,子串为abvd sl = 4
接下来我们分析一下其他特殊情况
子串sstr,子串长度sl
1.s = pwwkew
start = 0;
index = 0,sl = 1,sstr = p
index =1,sstr = pw,sl = 2;
index = 2,sstr = pww ->start = 上一个w的位置+1的位置也就是 start = 2;sstr = w,sl = 1
index = 3,sstr = wk,sl = 2
...
2.s = abba
start = 0
index = 0,sstr = a
index = 1,sstr = ab
index = 2,sstr = abb ->start = 2,sstr = b
index = 3,sstr = ba ->start = 1,sstr =bba
显然,我们发现index = 3时,就会出问题,因为这个时候,start肯定不能网前移,只能网后推,通常情况下我们需要加一个max
以下是源码:
/*
* @lc app=leetcode.cn id=3 lang=java
*
* [3] 无重复字符的最长子串
*/
// @lc code=start
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap map = new HashMap<>();
List lenList = new ArrayList<>();
char[] ca = s.toCharArray();
int max = 0;
//考虑到字符串只有1的情况
if(s.length() <= 1){
return s.length();
}
int start = 0;
for(int i =0;i
效率提升了很多,当然,效率还能提高,比如取消掉lenList,直接max,当然,这些细节的东西可以自己琢磨
总结下来就是:
start为起始,索引为终点的窗口扫过这组数据,判断节点重复,更新start从而更新不重复窗口。
时间复杂度是o(n)。
时间复杂度是o(n),上面的时间复杂度是o(n2)
...真特么diao