写点什么

算法题每日一练:无重复字符的最长子串

作者:知心宝贝
  • 2023-04-30
    江苏
  • 本文字数:1074 字

    阅读完需:约 4 分钟

算法题每日一练:无重复字符的最长子串

一、问题描述

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


题目链接:无重复字符的最长子串

二、题目要求

样例 1

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

样例 2

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

考察

1.字符串、滑动窗口2.建议用时20~35min
复制代码

三、问题分析

拿到这一题,首先确定属于字符串的应用,以样例 1 为例,我一开始的思路是:


从字符串逐个开始遍历,依次向后寻找以当前字符作为首位的最大子串。


abcabcbb第一位a             abc第二位b             bca第三位c             cab第四位a             abc......最后一位b           b
复制代码


我一开始的想法是哈希表(C++的 map 计数),如果当前这个字符前面的哈希表里面没有出现,那么字符串长度+1,这个字符哈希表+1。按照上面的步骤,逐步遍历。



但是这种算法效率也太差了,我们优化一下。



其实可以把原来的二层循环简化到一层,l r 作为双指针分别指向第一个字符,依次向后遍历。


如果 r 指向字符没出现,将它后一位的下标加入哈希表中,l 不变,r++。


如果 r 指向字符出现,l 需要变成上一个出现的字符后一位,这样可以保障[l,r]区间内不存在重复的字符。


可以依照力扣上面的几张图示,帮助理解。

四、编码实现

1.优化前

class Solution {public:    int lengthOfLongestSubstring(string s) {    int i,j,n=s.size(),ans=0,k=0;//初始化代码    map<char,int>m;//哈希表存储    for(i=0;i<n;i++)//每一个字符作为起点    {        m.clear();//清空        ans=0;//        for(j=i;j<n;j++)//向后寻找无重复字符        {            if(m[s[j]]==0)//找到了            {                ans++;//计数                m[s[j]]++;//标记            }            else//没找到直接退出                break;        }        k=max(k,ans);//寻找最大值    }    return k;//输出结果    }};
复制代码

2.优化后

class Solution {public:    int lengthOfLongestSubstring(string s) {        int l,r,n=s.size(),ans=0;//初始化变量        map<char,int>m;//哈希表        for(l=0,r=0;r<n;r++)//区间移动        {            if(m[s[r]]>0)//当前字符与哈希表里面冲突                l=max(l,m[s[r]]);//l移位            m[s[r]]=r+1;//哈希表存储下标的后一位            ans=max(ans,r-l+1);//求出最大值        }        return ans;//输出结果    }};
复制代码

五、测试结果


从 964ms->12ms,不优化了,满足了。

发布于: 刚刚阅读数: 3
用户头像

知心宝贝

关注

公众号:穿越计算机的迷雾 2022-03-07 加入

生于尘埃 溺于人海 死于理想高台

评论

发布
暂无评论
算法题每日一练:无重复字符的最长子串_数据结构_知心宝贝_InfoQ写作社区