【滑动窗口】+ leetcode_03:无重复字符的最长子串

⭐⭐:中等

题目描述

无重复字符的最长子串

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

解法一

把所有的子串全部列出来,暴力循环判断,这种解法在 leetcode上 直接超时。

public static int lengthOfLongestSubstring2(String s) {
    int max = 0;
    int len = s.length();
    for (int i = 0; i < len; i++) {
        for (int j = i + 1; j <= len; j++) {
            if (compare(s, i, j)) {
                max = Math.max(max, j - i);
            }
        }
    }
    return max;
}
//依次循环比较
public static boolean compare(String s, int i, int j) {
    Set<Character> set = new HashSet<>();
    for (int k = i; k < j; k++) {
        Character ch = s.charAt(k);
        if (set.contains(ch)) {
            return false;
        }
        set.add(ch);
    }
    return true;
}

时间复杂度:两个循环,加上判断子串满足不满足条件的函数中的循环,O(n³)。

空间复杂度:使用了一个 set,判断子串中有没有重复的字符。由于 set 中没有重复的字符,所以最长就是整个字符集,假设字符集的大小为 m ,那么 set 最长就是 m 。另一方面,如果字符串的长度小于 m ,是 n 。那么 set 最长也就是 n 了。综上,空间复杂度为 O(min(m,n))。

解法二

滑动窗口思想

找出从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案,其中括号中表示选中的字符以及最长的字符串:

  • (a)bcabcbb 开始的最长字符串为(abc)abcbb

  • a(b)cabcbb 开始的最长字符串为 a(bca)bcbb

  • ab(c)abcbb 开始的最长字符串为 ab(cab)cbb

  • abc(a)bcbb 开始的最长字符串为 abc(abc)bb

  • abca(b)cbb 开始的最长字符串为 abca(bc)bb

  • abcab(c)bb 开始的最长字符串为 abcab(cb)b

  • abcabc(b)b 开始的最长字符串为 abcabc(b)b

  • abcabcb(b) 开始的最长字符串为 abcabcb(b)

图解

我们定义两个指针i,j来控制窗口的移动和大小

【滑动窗口】+ leetcode_03:无重复字符的最长子串_第1张图片

public int lengthOfLongestSubstring(String s) {
    int len = s.length();
    int max = 0, i = 0, j = 0;
    //定义一个窗口
    Set<Character> set = new HashSet<>();
    while (i < len && j < len) {
        //如果不存在则加入
        if (!set.contains(s.charAt(j))) {
            //增大窗口
            set.add(s.charAt(j));
            j++;//索引从0开始,所以+1之后在计算
            max = Math.max(max, j - i);
        } else {
            //存在就删除窗口
            set.remove(s.charAt(i));
            i++;
        }
    }
    return max;
}

时间复杂度:在最坏的情况下,while 循环中的语句会执行 2n 次,例如 abcdefgg,开始的时候 j 一直后移直到到达第二个 g 的时候固定不变 ,然后 i 开始一直后移直到 n ,所以总共执行了 2n 次,时间复杂度为 O(n)

空间复杂度:同解法一,O(min(m,n))。

你可能感兴趣的:(leetcode,数据结构和算法,leetcode,算法)