LeetCode 3 – 无重复字符的最长子串

题目描述

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

示例 1:

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

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

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

题目分析

直接暴力枚举,双层循环,时间复杂度 O(n^2) ,显然不是好的做法。
使用双指针维护一个滑动窗口,用 HashSet 来确保窗口内字符不重复。
先用右指针尽可能的添加字符,无法添加时,就将左指针向右移动一位(同时在 set 中删除对应字符)。不断循环直到左指针移动到最右边,在这个过程中记录窗口的最大长度。
虽然代码上有2层循环,但从全局视角左指针和右指针都只会遍历一次字符串,因此时间复杂度是 O(n)

Java

public int lengthOfLongestSubstring(String s) {
    int ans = 0;
    int left = 0, right = 0;
    HashSet<Character> set = new HashSet<>();
    while (left < s.length()) {
        while (right < s.length() && !set.contains(s.charAt(right))) {
            set.add(s.charAt(right++));
        }
        ans = Math.max(ans, right - left);
        set.remove(s.charAt(left++));
    }
    return ans;
}

Kotlin

    fun lengthOfLongestSubstring(s: String): Int {
        var left = 0
        var right = 0
        var ans = 0
        val length = s.length
        val set = HashSet<Char>()
        while (left < length) {
            while (right < length && !set.contains(s[right])) {
                set.add(s[right++])
            }
            ans = ans.coerceAtLeast(right - left)
            set.remove(s[left++])
        }
        return ans
    }

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部