【力扣刷题】day1-3. 无重复字符的最长子串

力扣刷题笔记day2

3. 无重复字符的最长子串

题意

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

示例

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

分析

首先想到暴力解,利用两层循环,设置一个数组存储出现过的字符,外层循环为起始位,内层循环不断延申,当遇到存在过的字符时,中断内层循环。设置length,内层循环每循环一次,就判断是否有更长的长度,有就更新。

class Solution4 {
    public int lengthOfLongestSubstring(String s) {
        int length=0;
        for (int i = 0; i < s.length(); i++) {
            boolean[] num=new boolean[300];
            for (int j = i; j < s.length(); j++) {
                if(num[s.charAt(j)]){
                    break;
                }
                num[s.charAt(j)]=true;
                length=Math.max(length,j-i+1);
            }
        }
        return length;
    }
}

但是暴力解时间复杂度太高,为o(n*n)

这里参考kmp算法,改进代码,我们将每一次访问的元素的下标存起来,当重复时,让j等于旧元素下标+1,然后更新下标为新元素下表。同时,可能遇到abba这种字符串,处理这种字符串时,j会指向比当前元素下标更小的元素下标,比如j=2,执行过程中j可能会变成1。所以这里要加判断。

class Solution5 {
    public int lengthOfLongestSubstring(String s) {
        int length=0;
        HashMap<Character, Integer> map=new HashMap<>();
        int j=0;
        for (int i = 0; i < s.length(); i++) {
            if(map.containsKey(s.charAt(i))){
                if(j<=map.get(s.charAt(i))){
                    j=map.get(s.charAt(i))+1;
                }
                map.put(s.charAt(i),i);
            }
            else{
                map.put(s.charAt(i),i);
            }
            length=Math.max(length,i-j+1);
        }
        return length;
    }
}

总结

对于本题,利用到滑动窗口的思想

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!
还利用到了极其重要的数据结构——哈希表

【力扣刷题】day1-3. 无重复字符的最长子串_第1张图片

你可能感兴趣的:(力扣刷题,leetcode,算法,职场和发展)