Sword48——最长不含重复字符的子字符串
方法1——动态规划+哈希表
- 思路:使用Map记录已出现字符的最新下标,当再次遍历到相同字符时,计算其无重复字符子串的长度即可
- 特殊情况与临界分析:无
- 终止条件:遍历到最后一个字符完成操作
- 步骤:
- 将字符串转换为字符数组
- 定义Map存储字符及其对应下标
- 定义结果值、临时值
- for循环
- 参数:i从0开始,i小于字符数组长度
- 判断当前字符是否在Map中出现过,出现获取其下标,未出现获取为-1
- 将当前字符及其下标加入Map,即更新哈希表
- 获取此时以当前字符结尾的最长无重复子串长度
- 判断以当前字符结尾的字符串长度(i - 原字符下标),是否比之前的最长无重复子串要长
- 如果要长,则结果为最长无重复子串加1
- 否则即为i - 原字符下标
- 更新最长无重复字符的结果
- 返回结果
public int lengthOfLongestSubstring(String s) {
char[] chars = s.toCharArray();
Map<Character, Integer> dic = new HashMap<>();
int res = 0, tmp = 0;
for (int i = 0; i < chars.length; i++) {
int index = dic.getOrDefault(chars[i], -1);
dic.put(chars[i], i);
tmp = (tmp < i - index) ? (tmp + 1) : (i - index);
res = Math.max(res, tmp);
}
return res;
}
![方法1——动态规划+哈希表](https://i-blog.csdnimg.cn/blog_migrate/bf59c34db8c1c4769339e46ee0ca2cd2.png)
方法2——单指针+哈希表
- 思路:定义左指针从-1开始,使用Map记录已出现字符的下标,并计算最长无重复子串,当再次遍历到相同字符时,更新左指针
- 特殊情况与临界分析:无
- 终止条件:遍历到最后一个字符完成操作
- 步骤:
- 将字符串转换为字符数组
- 定义Map存储字符及其对应下标
- 定义结果值、左指针
- for循环
- 参数:i从0开始,i小于字符数组长度
- 判断当前字符是否在Map中出现过
- 出现则更新左指针,取当前位置与出现过的下标的最大值
- 这里取二者的最大值原因:是因为防止之前出现过此字符,导致更新后左指针回退
- 将当前字符及其下标加入Map,即更新哈希表
- 更新最长无重复字符的结果
- 返回结果
public int lengthOfLongestSubstring(String s) {
char[] chars = s.toCharArray();
Map<Character, Integer> dic = new HashMap<>();
int res = 0, left = -1;
for (int i = 0; i < chars.length; i++) {
if (dic.containsKey(chars[i])) {
left = Math.max(left, dic.get(chars[i]));
}
dic.put(chars[i], i);
res = Math.max(res, i - left);
}
return res;
}
![方法2——单指针+哈希表](https://i-blog.csdnimg.cn/blog_migrate/e41e510c65056af95d873fc2452f0827.png)