1、题意描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
举例:
示例 1:
输入: s = “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew” 输出: 3 解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
2、解题思路
要想解这个题我们得清楚以下几点:
1、题目告诉我们每一个子串的所有字符都必须是不重复的,所以我们得有一种思路就是逐个去遍历这个给定的串,然后动态的更新最左位置。
2、有了第一点的大体思路,我们得注意以下几个变量值。
2.1、当前字串的最左边的字符索引值。
2.2、当前字串的动态长度。
2.3、当前遍历历史中所有字串的最大长度。
3、所以现在具体思路就来了,我们去遍历给定的字符串,每一次都判断当前字串与历史的所有字串的最大长度哪个更长,然后将更长的保存在 max 临时变量中,然后有重复出现的话,就需要将重复的字符索引加一去替换最左的位置(这块也需要判断一下,具体看代码中解释)。
具体代码如下:
3、代码实现
class Solution {
public int lengthOfLongestSubstring(String s) {
// 如果字符串为空或者字符长度为0
if(null == s || s.length() == 0){
return 0;
}
// 表示当前字串的最大长度
int max = 0;
// 表示当前遍历字串的长度
int currCharMax = 0;
// 定义一个当前字串的最左位置
int left = 0;
// 定义一个临时的散列表,表示当前遍历的字串
Map<Character, Integer> map = new HashMap<>(s.length());
for (int index = 0; index < s.length(); index ++){
char currChar = s.charAt(index);
// 如果当前的HashMap存在这个字符
if(map.containsKey(currChar)){
// 将最左的位置移动到存在的后一位
// 这块的比较举个例子吧,就比如说 abba, 当第一个b重复时,left向后移动
// 当最后一个a重复时,但是他重复的是第一个b的前面字符,就相当于不算
left = Math.max(left, map.get(currChar) + 1);
}
// 将当前遍历到的字符放进Hash表
map.put(currChar,index);
// 计算出当前遍历的字串的最大的长度
currCharMax = index - left + 1;
// max一直保存的是遍历过之后的最大字串的最大长度
// 一旦当前的字串比之前的最大长度大,则替换掉历史的最大字串长度
max = Math.max(currCharMax, max);
}
return max;
}
}