题目:
无重复字符的最长子串
Given a string
s
, find the length of the longest substring without repeating characters.给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题分析:
题目要求连续, 我们考虑使用滑动窗口。 而这道题就是窗口大小不固定的滑动窗口题目,然后让我们求满足条件的窗口大小的最大值,这是一种非常常见的滑动窗口题目。
算法:
用一个 hashmap 来建立字符和其出现位置之间的映射。同时维护一个滑动窗口,窗口内的都是没有重复的字符,去尽可能的扩大窗口的大小,窗口不停的向右滑动。
如果当前遍历到的字符从未出现过,那么直接扩大右边界;
如果当前遍历到的字符出现过,则缩小窗口(左边索引向右移动),然后继续观察当前遍历到的字符;
重复(1)(2),直到窗口内无重复元素;
维护一个全局最大窗口 res,每次用出现过的窗口大小来更新结果 res,最后返回 res 获取结果;
最后返回 res 即可;
关键点:
map 记录出现过并且没有被删除的字符
滑动窗口记录当前 index 开始的最大的不重复的字符序列
class Solution {
public int lengthOfLongestSubstring(String s) {
// 首先判断是否是空串
if(s.length() == 0) return 0;
// 创建一个数组
Map<Character, Integer> map = new HashMap<>();
int maxLength = 0;
for(int i = 0, j = 0; i < s.length(); ++i){
// i是右边界,j是左边界
if(map.containsKey(s.charAt(i))){
// 如果重复了
j = Math.max(j, map.get(s.charAt(i)) + 1); // j左边界就像右移动
}
map.put(s.charAt(i), i);
maxLength = Math.max(maxLength, i-j+1); // 意思是,没有重复的,当前位置的i减去j所在的位置再加1就是当前新增加的长度,就是总长度
}
return maxLength;
}
}