无重复字符的最长子串

2020-04-16  本文已影响0人  hbhey

题目描述

给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。

解析

滑动窗口算法

滑动窗口算法用于对给定的大缓冲区或数组的特定窗口大小执行所需的操作(即在遍历大缓存区或数组时, 对其特定的窗口大小执行特定操作)。目的是将很少出现问题的嵌套for循环转换为单个for循环,从而降低时间复杂度。例如: 找出某数组中和最大的子数组, 规定子数组元素个数为3, 即窗口大小为3, 当然窗口大小也可以是动态的。具体过程如下:


滑动过程

代码实现

实现一

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int record = 0,i = 0,j = 0;  // record记录最长子串长度
        int length = s.length(); 
        Set strSet = new HashSet();  // 使用HashSet作为滑动窗口
        while(i < length && j < length){
            if(!strSet.contains(s.charAt(j))){  // s.charAt(j)不在strSet中
                strSet.add(s.charAt(j));
                j++;
                record = Math.max(record, j - i);
            }else{
                strSet.remove(s.charAt(i));
                i++;
            }
        }
        return record;
    }
}

实现二

该实现是对滑动窗口的优化,即在窗口中存在与当前元素相同的字符,直接把窗口左端移动到相同字符的后一位,而不是一步一步的移动左端窗口。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int length = s.length(), record = 0;
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        for(int i = 0, j = 0; j < length; j++){
            if(map.containsKey(s.charAt(j))){  // 包含了有相同字符
                i = Math.max(map.get(s.charAt(j)),i);  // 把i定位到存储在map中且与s.charAt(j)相同的字符的下一个索引位置
            }
            record = Math.max(record,j - i + 1);  // + 1是因为前面已经排除了相同字符, 遂可把s.charAt(j)字符加入参与长度计算 
            map.put(s.charAt(j), j + 1);  // 把s.charAt(j)索引+1是方便i的定位(定位到相同元素的后一位)
        }
        return record;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读