无重复字符的最长子串
题目描述
难度:中等。
解决方法
方法一:哈希表
使用滑动窗口和哈希表来维护当前的无重复字符子串。在遍历过程中,不断更新最长子串的长度。
使用两层嵌套循环遍历字符串,外层循环从字符串的开头到末尾,内层循环从外层循环的当前位置开始,一直到字符串末尾。在内层循环中,创建一个哈希表hashTable用于存储字符和它们的出现次数。同时,创建一个变量count用于记录当前无重复字符子串的长度,初始值为0。
在内层循环中,检查当前字符是否已经存在于hashTable中。如果不存在,将字符添加到 hashTable中,并将count 增加1。如果发现重复字符,就退出内层循环,因为这表示当前子串中出现了重复字符。
在每次内层循环结束后,将count与maxCount比较,以记录最长的无重复字符子串长度。
将hashTable设置为nul,释放内存。
class Solution {
public int lengthOfLongestSubstring(String s) {
int len = s.length();
int maxCount = 0;
for(int i=0;i<len;i++){
int count = 0;
Map<Character,Integer> hashTable = new HashMap<>();
for(int j=i;j<len;j++){
if(!hashTable.containsKey(s.charAt(j))){
hashTable.put(s.charAt(j),0);
count++;
}else{
break;
}
}
if(count>maxCount){
maxCount = count;
}
hashTable = null;
}
return maxCount;
}
}
方法二:滑动窗口
这是看了官方题解才做出来的方法。
使用了滑动窗口和集合来维护当前的无重复字符子串,并在遍历过程中不断更新最长子串的长度。
创建一个HashSet类型的集合strSet,用于存储当前正在考察的无重复字符子串中的字符。
初始化变量j,初始值为 -1。j表示当前无重复字符子串的结束位置。使用for循环遍历字符串s,外层循环从字符串的开头到末尾。在外层循环中,首先检查是否需要从strSet中移除字符。如果i不等于 0,表示当前字符不是字符串的开头,那么需要将前一个字符从strSet中移除。
使用内层while循环,从位置j+1开始逐个字符向后检查,直到遇到重复字符或者达到字符串末尾。在此过程中,将字符逐个添加到strSet中,并更新j的值,表示当前无重复字符子串的结束位置。在内层循环结束后,计算当前无重复字符子串的长度j-i+1,并将其与maxCount进行比较,选择较大的值更新maxCount。
继续外层循环,直到遍历完整个字符串s,期间不断更新maxCount,以获取最长无重复字符子串的长度。
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> strSet = new HashSet<>();
int len = s.length();
int j = -1;
int maxCount = 0;
for(int i=0;i<len;i++){
if(i!=0){
strSet.remove(s.charAt(i-1));
}
while(j+1<len && !strSet.contains(s.charAt(j+1))){
strSet.add(s.charAt(j+1));
j++;
}
maxCount = Math.max(maxCount,j-i+1);
}
return maxCount;
}
}
加油!