链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

解题思路:滑动窗口

大家看到滑动窗口这种类型题不要怕,本质上它就是双指针。

初始化:

  • 初始化变量 Map<Character,Integer> map = new HashMap<>(),map 的 key 存储遍历的字符,value 存储当前遍历字符在字符串中的索引
  • 初始化变量 int max,表示最长的无重复子串的长度,作为返回值
  • 初始化变量 int left,作为滑动窗口的左指针
  • 变量 int i,作为遍历指针,同时它也是滑动窗口的右指针

算法思路:

  • 滑动窗口维护最长的无重复子串
  • 遍历字符串的过程中,如果 map 已经包含当前字符 char[i],则说明我们需要重新维护当前的滑动窗口,让左指针left 更新为 leftmap.get(chars[i]) + 1)中较大的那一个
  • 将当前的字符和字符索引更新到 map 中
  • 更新 max

流程模拟:

image.png
image.png
image.png
image.png
image.png
image.png
image.png

代码

  1. class Solution {
  2. public int lengthOfLongestSubstring(String s) {
  3. char[] chars = s.toCharArray();
  4. Map<Character,Integer> map = new HashMap<>();
  5. int left = 0;
  6. int max = 0;
  7. for(int i = 0; i < chars.length; i++){
  8. if(map.containsKey(chars[i])){
  9. left = Math.max(left,map.get(chars[i]) + 1);
  10. }
  11. map.put(chars[i],i);
  12. max = Math.max(max,i - left + 1);
  13. }
  14. return max;
  15. }
  16. }

复杂度分析

  • 时间复杂度:

N 为字符串的长度,我们只需要从头至尾遍历一次字符串就可以得到目标解,所以时间复杂度为

  • 空间复杂度:

我们申请了一个哈希表,哈希表中需要存储字符串中所有不相同的字符个数,记作 M,所以额外空间复杂度为