LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路

简介: 本文回顾了笔者对LeetCode第三题(Longest Substring Without Repeating Characters)的解题和优化思路,希望有兴趣的读者来一起广泛讨论

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos
  • 笔者在完成LeetCode第三题(Longest Substring Without Repeating Characters)时,经历了设计、实现、优化三个阶段,于是通过这个三部曲系列,将当初的整个过程重现,希望有兴趣的读者来一起讨论;

三部曲完整链接

  1. 《LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之一:解题思路》;
  2. 《LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之二:编码实现》;
  3. 《LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化》;
  • 先来看下优化后的最终效果,如下图,编程语言是Java,17毫秒完成,超越99.94%的提交方案:

在这里插入图片描述

三部曲说明

  • 整个系列由三篇文章组成:
  • 第一篇,也就是本文,描述基本解题思路;
  • 第二篇,根据解题思路完成初版的代码实现,目标是保证功能正常,能在LeetCode网站提交成功;
  • 第三篇,针对初版代码做了两轮优化,每轮都有一个优化的重点,最终将耗时从40ms以上优化到17ms;

题目简介

  1. 题目地址是:https://leetcode.com/problems/longest-substring-without-repeating-characters/
  2. 题目内容:输入一个字符串例如"abcabcbb",找到最长的不重复的字符串的长度返回,这里应该返回的是"abc"的长度3;

解题思路简述

  • 该题的关键是设计一个"滑动窗口",里面存的是最长的不重复字符串,一开始这个窗口是空的,如下图,绿色代表滑动窗口,蓝色的是外部输入的字符串:

在这里插入图片描述

  • 从字符串的第一个元素开始,执行这个逻辑:
  1. 用一个变量保存当前已经发现的最大长度,假设名为maxLen;
  2. 如果当前检查的元素在窗口中没有,就加入窗口,例如窗口中已经有了"ab",当前是"c",那么窗口中最大长度加一;
  3. 如果当前检查的元素在窗口中存在,例如窗口中已经有了"abc",当前检查的元素是"a",这个"a"在窗口总已经存在了,窗口作调整,窗口中的"a"和它左侧的所有元素全部移除窗口,再把当前检查的"a"元素加入窗口;
  4. 拿当前窗口的长度和maxLen比较,大的值存入maxLen中;
  5. 继续检查字符串的下一个元素,逻辑是前面的步骤;

思路详细图解

  • 以前面的"abcabcbb"为例,来把上述逻辑用图片演示一遍;
  • 检查完第一个元素后,窗口效果如下图,可见第一个元素已经纳入窗口中:

在这里插入图片描述

  • 检查完第三个元素后,效果如下图,maxLen等于3,三个元素纳入窗口:

在这里插入图片描述

  • 检查到第四个元素是"a",那么窗口的左侧和右侧都开始滑动,maxLen等于3,当前窗口中的长度也是3,因此maxLen不变,如下图:

在这里插入图片描述

  • 继续检查第5个元素,这次遇到的"b"在窗口中也存在,处理如下图:

在这里插入图片描述

  • 继续检查第6个元素,这次遇到的"c"在窗口中也存在,所以第一个"c"移出窗口,第二个"c"加入窗口,窗口内的元素还是3个,所以maxLen保持不变,处理如下图:

在这里插入图片描述

  • 检查第7个元素"b",窗口中已经有"b"了,所以左侧窗口向右收缩,将里面原有的中的"b"移出,右侧窗口向右扩张,将第7个元素"b"纳入窗口中,此时窗口中元素数量为2,小于maxLen,所以maxLen不变,如下图:

在这里插入图片描述

  • 检查第8个元素"b",发现窗口中已经有"b"了,只能将窗口中的"b"(第7个元素)和它左侧的"c"(第6个元素)都从窗口中移出,再把第8个元素纳入窗口,此时窗口中只有一个元素,因此maxLen不变,如下图:

在这里插入图片描述

  • 数组已经遍历完毕,返回maxLen=3,解题结束;
  • 以上就是解题思路,用代码来实现整个思路并不难,下一篇文章我们来看下基本的代码实现;

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关文章
Leetcode 516. Longest Palindromic Subsequence
找到一个字符串的最长回文子序列,这里注意回文子串和回文序列的区别。子序列不要求连续,子串(substring)是要求连续的。leetcode 5. Longest Palindromic Substring就是求连续子串的。
49 0
|
机器学习/深度学习 JavaScript 前端开发
LeetCode 51.N皇后(JavaScript 解题)
LeetCode 51.N皇后(JavaScript 解题)
61 0
|
1月前
|
人工智能 自然语言处理 程序员
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
欢迎来到工程师令狐小哥的频道。本文介绍如何利用AI工具高效刷LeetCode,通过通义灵码插件在IntelliJ IDEA中实现代码生成、优化、单元测试等功能,提升编程学习效率。
65 1
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
【力扣-TS解题】1、回文数
【力扣-TS解题】1、回文数
51 0
|
Java
Leetcode 3. Longest Substring Without Repeating Characters
此题题意是找出一个不包含相同字母的最长子串,题目给出了两个例子来说明题意,但这两个例子具有误导性,让你误以为字符串中只有小写字母。还好我是心机boy,我把大写字母的情况也给考虑进去了,不过。。。。字符串里竟然有特殊字符,于是贡献了一次wrong answer,这次我把ascii字符表都考虑进去,然后就没问题了。这个故事告诫我们在编程处理问题的时候一定要注意输入数据的范围,面试中可以和面试官去确认数据范围,也能显得你比较严谨。
50 3
|
JavaScript 前端开发 算法
LeetCode 37.解数独(注释完整+JavaScript解题)
LeetCode 37.解数独(注释完整+JavaScript解题)
82 0
|
算法 测试技术 程序员
如何提高力扣(Leetcode)的解题能力?
如何提高力扣(Leetcode)的解题能力?
|
SQL 数据库
力扣SQL之路:解题分析与实战技巧
力扣SQL之路:解题分析与实战技巧
203 0
leetcode 315周赛 解题报告
leetcode 315周赛 解题报告
66 0
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行