题目梗概:
找出指定字符串的最长无重复字符的子串的长度。
解题思路:
想要直接找出指定字符串的最长无重复字符的子串不太容易,不过本题也不是要求做题者找出该子串,而是要求找出最长无重复字符的子串的长度,因此在难度上减轻了不少。要想找出字符串的最长子串,肯定要遍历字符串的每个字符,然后在遍历过程中判断当前的字符是否在之前出现过,如果没有出现过则最长子串的长度加一,如果出现过则表示从字符串的起始点开始到当前的字符为止的子串不符合要求,因此要重新定义起始点,这道题的关键就在于如何确定这个起始点。首先定义一个变量maxLen用于存储最长子串的长度,然后定义一个变量j用于存储起始点,j的初始值为为字符串的第一个字符的下标,即0。接着我需要一个容器用于存储遍历过程中得到的字符,并且该容器能够让我快速判断之前有无存储过重复字符,因为我使用的编程语言是Java,因此想到使用Map存储遍历过程中得到的字符,key存储字符,value存储字符在字符串中的下标,通过containsKey()方法判断当前字符是否已存储过,如果已经存储过则通过get()方法获取到字符对应的下标,加一,然后跟j进行比较,保留较大值并赋值给j,通过这样能保证字符串从j开始直到当前遍历到的字符之间无重复字符,然后更新value值,这样当下次再遇到重复字符时才能保证比较的是离当前字符最近的那个。maxLen的长度与j有关,每次遍历时求出当前的无重复字符子串的长度然后与maxLen进行比较,保留较大值并赋值给maxLen,这样就能保证即使当前的子串并不是最大的maxLen的值也依然正确。
解题算法:
- 方案一(Java实现)
public static int lengthOfLongestSubstring(String s) {
int maxLen = 0; // 最长子串的长度
String substring = ""; // 符合要求的子串
for (int i = 0; i < s.length(); i++) {
if (substring.contains(s.charAt(i) + "")) {
int start = substring.indexOf(s.charAt(i));
start++;
substring = substring.substring(start) + s.charAt(i);
} else {
substring = substring.concat(s.charAt(i) + "");
}
maxLen = Math.max(maxLen, substring.length());
}
return maxLen;
}
- 方案二(Java实现)
class Solution {
public int lengthOfLongestSubstring(String s) {
int maxLen = 0; // 存储字符串的最长的无重复字符的子串的长度
Map<Character, Integer> map = new HashMap<Character, Integer>(); // 存储字符串中的每个字符及其在字符串中的下标,遇到重复字符则更新下标
for(int i=0,j=0; i<s.length(); i++){ // j用于存储字符串中字符的下标,表示从当前下标开始的字符串的子串无重复字符
if(map.containsKey(s.charAt(i))){
j = Math.max(map.get(s.charAt(i))+1, j);
}
maxLen = Math.max(i-j+1, maxLen);
map.put(s.charAt(i), i);
}
return maxLen;
}
}