题目
题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
解题思路
这个题目是前边面试美团一面时遇到过。仍然是从题目入手,不含有重复字符串,所以需要记录每个字符出现的最后一个字符出现的位置,用于统计当前两个重复字符之间的长度(diff)。用curDiff记录当前不含重复字符的字符串长度。
- 对于包含重复字符的处理逻辑
- curDiff < diff,则curDiff = curDiff + 1,举个例子,abcbcabb,当统计到abcbca时,a的上一次出现的位置在0,当前的curDiff为2,当统计到a时,diff为5,因此,当前的最长不重复的子字符串为bca
- 其他,则curDiff = diff; 举个例子,abcabc,当统计到abca时,当前的最长不含重复字符的字符串为bca。
- 对于不包含重复字符的处理逻辑
- curDiff = curDiff + 1;
代码逻辑
/**
* @author woniu
* @date 2022/5/19 11:49
**/
public class Test {
public Integer lengthOfLongestSubstring(String str) {
// 用于记录最长长度
int max = 0;
// 用于记录当前的最长字符串
int curDiff = 0;
// key: 出现的字符,value: 最后一次出现的位置
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < str.length(); i++) {
if (map.containsKey(str.charAt(i))) {
int diff = i - map.get(str.charAt(i));
// 如果差值大于当前长度,则继续
if (diff > curDiff) {
curDiff = curDiff + 1;
} else { // 这里相当于再当前判断最长字符串中出现了重复。当前最长子串即为两个相同字符的中间差
curDiff = diff;
}
} else {
curDiff++;
}
// 获取当前的最大值。
max = Math.max(max, curDiff);
map.put(str.charAt(i), i);
}
return max;
}
}