3.Longest Substring Without Repeating Characters

本文介绍了一种使用滑动窗口算法解决寻找字符串中最长不重复子字符串的方法。通过HashSet作为滑动窗口,避免了双重循环的高时间复杂度,实现了O(1)的时间复杂度。详细讲解了算法思路并给出了代码实现。
摘要由CSDN通过智能技术生成

题目描述:

Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

思路

要求最长的没有重复元素的连续子字符串,最简单的是方法是使用双重循环,遍历所有的子字符串,并一一判断是否有重复元素,没有重复元素,再更新子字符串的最大值。这种暴力破解法时间复杂度太高,超时。

for (int i = 0; i < n; i++)
    for (int j = i + 1; j <= n; j++)
        //判断子字符串是否有重复元素
        if (allUnique(s, i, j)) 
            ans = Math.max(ans, j - i);

上面这种暴力法,有一个可以改进的地方,就是当我们要判断 sij 是否有重复元素时,我们在此之前已经判断了 sij1 是否有重复元素了,无需重复判断,我们只需要检查 sj 是否在子串 sij1 中就可以了。可以借助HashSet实现。通过使用HashSet作为一个滑动窗口,检查当前的字符是否在一个字符串中,时间复杂度只有O(1)。Set是不含重复元素的集合。
滑动窗口是一个通常用于数组或字符串问题的抽象概念。一个窗口是数组或字符串中的一系列元素,这些元素通常由开始和结束索引定义,例如[i,j)(左闭,右开)。滑动窗口是一个窗口“滑动”它的两个边界到特定的方向。例如,如果我们滑动[i,j)到右边1个元素,那么它就变成[i+1,j+1)(左闭,右开)。
回到我们的问题。我们使用HashSet来存储当前窗口中的字符[i,j)(初始时j=i)。然后我们将指数j右移。如果不是在HashSet中,我们会进一步滑动j。一直到 sj 已经在HashSet中了。我们发现没有重复字符的最大子字符串从索引i开始。遍历索引i,就得到了答案。

代码:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值