力扣:2.无重复字符的最长子串(滑动窗口)

无重复字符的最长子串

一、题目

给定一个字符串 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 由英文字母、数字、符号和空格组成

二、代码

代码1:暴力求解

复杂度 O ( n 3 ) O(n^3) O(n3),执行运行超过6.84%用户,内存消耗超过82.01%用户

class Solution {
public:
    int lengthOfLongestSubstring(string s) { 

        if(s.empty())return 0;
        if(s.size()==1)return 1;

        vector<int> num(s.size(), 0);

        for(int i=0;i<s.size();i++){
            bool repeat=false;
            for(int j=i+1;j<s.size();j++){
                for(int k=i;k<j;k++){
                    if(s[k]==s[j]){
                        repeat=true;
                        num[i]=j-i;
                        break;
                    }
                }
                if(repeat)break;
                else num[i]=j-i+1;
            }
        }
        sort(num.begin(),num.end());
        return num[num.size()-1];
    }
};

代码2:力扣用户题解

复杂度 O ( n ) O(n) O(n),执行运行超过98.32%用户,内存消耗超过82.32%用户
思路

  1. 滑动窗口,保证每个窗口里字母都是唯一的请添加图片描述
  2. 使用 vector m 来记录一个字母如果后面出现重复时,i 应该调整到的新位置 21. 所以每次更新的时候都会保存 j + 1 ,即字母后面的位置。
  3. j 表示子串的最后一个字母,计算子串长度为 j - i + 1。

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> m(128, 0);
        int ans = 0;
        int i = 0;
        for (int j = 0; j < s.size(); j++) {
            i = max(i, m[s[j]]);
            m[s[j]] = j + 1;
            ans = max(ans, j - i + 1);
        }
        return ans;
    }
};
  • 作者:Ikaruga
  • 链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/

个人理解:题解中最重要的点时针对左边界i的设计,i的动作主要为两部分,一个是子串无重复时候i保持原位置,j继续向后扫描;二是当扫描到第j个元素的数与前边出现重复时,i定位到前一个重复元素的之后,如此循环,实现滑动窗口。

三、本题值得注意的点

  1. 针对此题,滑动窗口无疑是一个复杂度各方面较小的解决方案。
  2. max()或者min()函数复杂度为 O ( 1 ) O(1) O(1),值得被多次使用。

四、总结

本题主要针对运行时间考察,滑动窗口的方法可大大减少复杂度,进而实现最优求解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值