leetcode-无重复字符的最长子串
基本思路
基本思路就是利用滑动窗口,设置两个指针,i和j,分割出来窗口中的子串,如果是没重复子串,则j继续向前走,如果出现重复子串,那么i往前走,并且进行判断是否出现无重复子串,如果出现便j往前走。
基本就是 有无重复子串,j向前走,没有则i向前走缩小窗口,结束条件应该是两者都到达串尾。
实现代码
class Solution {
private HashMap<Character,Integer> map = new HashMap<>();
public int lengthOfLongestSubstring(String s) {
int i = 0,j=0;
int max = 0;
while(i<s.length() && j<s.length()){
String temp = s.substring(i,j+1);
if(isChildStr(temp)){
if(temp.length()>=max){
max = temp.length();
}
j++;
}else{
i++;
}
}
return max;
}
public boolean isChildStr(String str){
for(int i = 0;i<str.length();i++){
if(!map.containsKey(str.charAt(i))){
map.put(str.charAt(i),1);
}else{
map.clear();
return false;
}
}
map.clear();
return true;
}
}
网上思路
看评论区思路也是滑动窗口,该思路的基本流程是:
1.散列表初始化为-1,并作为记录字符出现位置的表,窗口起始位置设为0
2.窗口起始位置和(字符出现位置+1)进行比较,并将较大值赋值给其实窗口。如果字符从未出现,那么窗口的起始地址一直为0,否则则是(字符出现位置+1),这样可以缩小窗口
3.计算当前窗口大小,并和最大长度比较赋值。
4.散列表中记录字符出现的位置。记录后如果再次出现该字符,那么窗口就会移动到上个字符出现的位置的下一个位置。
实现代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
// 记录字符上一次出现的位置
int[] last = new int[128];
for(int i = 0; i < 128; i++) {
last[i] = -1;
}
int n = s.length();
int res = 0;
int start = 0; // 窗口开始位置
for(int i = 0; i < n; i++) {
int index = s.charAt(i);
start = Math.max(start, last[index] + 1);
res = Math.max(res, i - start + 1);
last[index] = i;
}
return res;
}
}