每日一题—— 无重复字符的最长子串

134 阅读1分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战

题目描述

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

示例 1:

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

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

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

提示:

0 <= s.length <= 5 * 104 s 由英文字母、数字、符号和空格组成

解题思路

主要是用到了滑动窗口和双指针的思想,维持好一个窗口,在每一次加入新元素之前,用左指针和右指针遍历整个窗口,如果发现重复元素,即增大左指针到重复元素之后,这样做就可以使滑动窗口收缩,保证窗口内没有重复元素。

具体实现:编写两重循环,第一重循环用于滑动窗口的右边界扩张,不断吸收新的元素;第二重循环用于判断窗口内是否有重复的元素。

代码实现

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int right = 0, left = 0;
        int max = 1;// 定义最后的答案
        int length = s.size();
        if(length == 0 ) return 0;
        while(s[right + 1] != '\0')
        {
            right ++ ;// 保证有新的元素进入窗口
            for(int t = left;t <= right - 1;t ++)
            {
                if(s[t] == s[right])
                {
                    left = t + 1;// 收缩窗口到指定位置,让左指针来到新的元素之后
                    break;
                }
            }
            if((right - left + 1) > max)// 不断更新窗口的最大值
                max = right -left +1;
        }
        return max;
    }
};

注意:由于用到了两重for循环,时间复杂度为O(n`2),但只用到了一个数组来模拟,空间复杂度为O(n)。