3. 【中等】无重复字符的最长子串

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。

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

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

【解】

滑动窗口。
一个长度为n的字符串的子串共1/2 n(n+1)个。这个结果是按照起始位置来分类得到的:左端(起始位置)位于0, 1,…, n-1的子串分别有n, n-1,…, 1个。
不难发现,若按照左端升序列举这些子串,则它们的右端(终止位置)也是递增的。于是,便可按照滑动窗口的基本思想,解决此问题。
需要两个数a, b表示子串s[a, b]。初始时,a=b=0。接下来:
·若s[b+1]不在当前子串s[a, b]中重复,则令b自增。
·否则,令a自增。
当b=n-1时,容易验证:若继续枚举下去,统计出的子串长度也不会再增加,算法终止。
可以看出,在执行算法的过程中,a, b都是只增不减的,即:在操作“判定字符s[b+1]是否已存在于当前子串s[a, b]”能够在O(1)内完成的条件下,算法的时间复杂度为O(n),n为给定的字符串s的长度。并且,子串s[a, b]始终保持各个字符都不相同。

【优化】

为了验证子串s[a, b]是否确实每个字符都不相同,最容易想到的实现之一,就是将每个字符都存入一个集合(std::set或std::unordered_set)里。开始时,字符s[0]位于集合内;b自增前,字符s[b+1]要放入该集合;a自增前,字符s[a]要从集合中删去。std::set是采用红黑树实现的,若使用std::set判重,则算法的最坏时间复杂度达到O(n log⁡|Σ| ),其中|Σ|为无重复字符的最长子串的长度,也就是字母表Σ含有的不同字符的个数——英文字母、数字和特殊符号(含空格)的总数。若采用std::unordered_set判重,则总的时间复杂度维持在O(n)。但是此时集合中的每个元素都只是单个ASCII字符,为了查找指定的ASCII字符是否已包含在集合中,而计算哈希并在集合中索引,具有不少不必要的开销。该方案的一份实现代码是:

#include <algorithm>
#include <unordered_set>class Solution {public:int lengthOfLongestSubstring(const string& s) {if (s.empty()) return 0;size_t a = 0, b = 0;unordered_set<char> u{ s[0] };size_t m = 1;while (b != s.size() - 1) {switch (u.emplace(s[b + 1]).second) {case true:++b;m = max(m, u.size());break;case false:u.erase(s[a]);++a;break;}}return m;}
};
用时:36 ms;内存占用:14 MB。两项都只优于10%+的用户。

为了缩短判重的常数时间,采用std::bitset来为每个可能出现的字符记录其是否位于子串中。开始时,字符s[0]位于集合内;b自增前,字符s[b+1]要放入该集合(对应位置记为true);a自增前,字符s[a]要从集合中删去(对应位置记为false)。字符串的每一个字符都在7位ASCII的范围内,所以该std::bitset需要的长度不超过128位。根据字符的ASCII码确定其在该std::bitset中的位置。代码:

#include <algorithm>
#include <bitset>class Solution {public:int lengthOfLongestSubstring(const string& s) {if (s.empty()) return 0;size_t a = 0, b = 0;bitset<128> n;n[s[0]] = true;char c;size_t lmax = 1, l = 1;while (b != s.size() - 1) {c = s[b + 1];switch (n[c]) {case false:n[c] = true;++b; ++l;lmax = max(lmax, l);break;case true:n[s[a]] = false;++a; --l;break;}}return lmax;}
};
优化后,用时:4 ms,超过97.50%的用户;内存占用:6.5 MB,低于99.96%的用户。

【评注】

1、注意特判。本题中,输入空串时,需要单独处理。
2、子串是从原字符串中截取的,也就是说,必须是原串中连续的一段。

【LeetCode 3-中等】无重复字符的最长子串(高清截图)相关推荐

  1. 刻意练习:LeetCode实战 -- Task16. 无重复字符的最长子串

    背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务.本期训练营采用分类别练习的模式,即选择了五个知识点(数组.链表.字符串.树.贪心算法),每个知 ...

  2. LeetCode Algorithm 3. 无重复字符的最长子串

    3. 无重复字符的最长子串 Ideas 这题有点KMP那味了. 首先定义三个变量: left:-1,当前处理字符串长度的左索引的前一位 res:0,最长子串长度 idx:{},最长子串中每个字符出现的 ...

  3. 【Leetcode 3】无重复字符的最长子串

    题目描述 2020年8月25日更新 一次遍历 思路: (1)一次遍历,用list存放遍历的连续不重复的子串,当遍历到重复的字符时,用index()方法获得list当中重复字符a的索引,然后将list重 ...

  4. leetcode算法题--无重复字符的最长子串

    题目地址: https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ https://leetc ...

  5. LeetCode刷题——无重复字符的最长子串

    目录 一.题目描述 二.题解 三.源码 一.题目描述 二.题解 三.源码 class Solution(object):def lengthOfLongestSubstring(self, s):&q ...

  6. LeetCode 每日一题 3. 无重复字符的最长子串

    LeetCode 每日一题 3. 无重复字符的最长子串   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创 ...

  7. 【LeetCode】无重复字符的最长子串【滑动窗口法】

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  8. LeetCode 3. 无重复字符的最长子串(滑动窗口+哈希)

    1. 题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 " ...

  9. LeetCode题库整理【Java】—— 3 无重复字符的最长子串

    LeetCode题库整理[Java] ## 3 无重复字符的最长子串 题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" ...

  10. 【LeetCode】【HOT】3. 无重复字符的最长子串(哈希表)

    [LeetCode][HOT]3. 无重复字符的最长子串 文章目录 [LeetCode][HOT]3. 无重复字符的最长子串 package hot;import java.util.HashMap; ...

最新文章

  1. 专访卢政:TSF如何助力企业微服务开发
  2. 使用JavaScript调用手机平台上的原生API
  3. 根据日期累计求和_excel条件求和技巧:应用SUMIF函数计算客户余款
  4. java exec mvn_maven---常用插件之EXEC
  5. 多项目开发下的dll文件管理
  6. 子集生成 --二进制法
  7. Kali linux 渗透测试技术之搭建WordPress Turnkey Linux及检测WordPress 应用程序漏洞
  8. java servlet 返回404_java项目访问servlet出现404
  9. 用户登录问题python_Python Flask单点登录问题
  10. php curl使用详解
  11. TCP 之 抓包分析
  12. ubuntu显卡测试软件,Linux显卡性能测试程序Unigine Valley 和 Unigine Heaven
  13. 万用表使用心得-测量不准点的地方
  14. Win8电脑音效怎么调?电脑音效设置方法
  15. Win10耳机插上没反应,外放正常怎么解决?
  16. 风口的猪(小米实习生笔试)
  17. 淘宝评价计分规则,店铺信用评价如何累计
  18. 卓海科技冲刺创业板:拟募资5.47亿 相宇阳控制52.9%股权
  19. SassScript(sass使用)
  20. 计算机管理中be启动不了,绝地求生BE服务启动不了怎么办 BE服务无法启动的解决方法...

热门文章

  1. Java调用linux指令工具类,直接执行cmd,执行grep指令返回结果,执行sed追加指令,hdfs下载指令,获取文件行数
  2. 科学计算机读书报告单,科学网—读书报告-20171016 - 梁斌的博文
  3. 后知后觉者的学习方法
  4. 亲述真实经历--“人工智能培训机构”的“坑”,希望更多像我这样的人不要吃了第一次亏才后知后觉
  5. Vue使用Echarts实现数据可视化
  6. 2019SUCTF EasyWeb
  7. 5分钟搞定OKR工作法
  8. python 文件去重
  9. STC系列芯片的串口通信编程
  10. 向服务器上传文件路径变为\fakepath问题