LeetCode #3

本贴最后更新于 2445 天前,其中的信息可能已经时移世改

问题:给定一个字符串,找出不含有重复字符的最长子串的长度。
示例:

输入: "abcabcbb"
输出: 3
解释: 无重复字符的最长子串是 "abc",其长度为 3。

思路:

  1. 暴破,从位置 0 开始,把遇到的字符放到 Set 中,如果有重复则向前推进
  2. 空间换时间,记录各个字符的位置,在遇到重复字符时向前推进,但直接跳到已有的重复字符之后一个字符开始计算
  3. 思路 2 的实现上的优化,直接用 String.charAt()获取单个字符,不先把整个字符串转换成数组(因为 String 底层就是字符数组了)

1000 万个随机字符的字符串耗时:

  1. cost: 3489 ms
  2. cost: 312 ms
  3. cost: 305 ms
    思路 3 有较大概率略微快于思路 2,但都比思路 1 快 10 倍以上,理论上字符串越长差别越明显

代码:

package xyz.quxiao.play.lab.leetcode; import com.google.common.base.Stopwatch; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.RandomStringUtils; /** * 给定一个字符串,找到最长不含相同字符的字串长度 * * @author 作者 :quxiao 创建时间:2017/11/7 18:21 */public class Problem3 { public static void main(String[] args) { String s = randomStr(); Stopwatch sw = Stopwatch.createStarted(); int r1 = lengthOfLongestSubstring(s); sw.stop(); System.out.println(r1 + " cost: " + sw.elapsed(TimeUnit.MILLISECONDS) + " ms"); sw.reset(); sw.start(); int r2 = lengthOfLongestSubstring2(s); sw.stop(); System.out.println(r2 + " cost: " + sw.elapsed(TimeUnit.MILLISECONDS) + " ms"); sw.reset(); sw.start(); int r3 = lengthOfLongestSubstring3(s); sw.stop(); System.out.println(r3 + " cost: " + sw.elapsed(TimeUnit.MILLISECONDS) + " ms"); sw.reset(); } public static String randomStr() { int max = 10000000; return RandomStringUtils.randomAlphabetic(max); } // 思路1:暴破,从0开始遍历每个字符加到set中,如果成功了比较当前长度与max大小;否则推进 public static int lengthOfLongestSubstring(String s) { if (s == null || s.length() == 0) { return 0; } int max = 0; char[] chars = s.toCharArray(); int len = chars.length; int idx = 0; while (idx < len) { // 计算该idx的最长字串 int start = idx; Set set = Sets.newHashSet(); while (start < len && set.add(chars[start++])) { } if (set.size() > max) { max = set.size(); } idx++; } return max; } // 思路2:空间换时间,记录各个字符的位置,在遇到重复字符时向前推进,但直接跳到已有的重复字符之后一个字符开始计算 public static int lengthOfLongestSubstring2(String s) { if (s == null || s.length() == 0) { return 0; } int max = 0; char[] chars = s.toCharArray(); int len = chars.length; int i = 0; // 已经清除的最后一个idx,初始时-1表示未清除任何字符 int lastClearIdx = -1; Map cMap = new HashMap<>(); while (i < len) { char c = chars[i]; // 不存在 if (!cMap.containsKey(c)) { cMap.put(c, i); max = Math.max(max, cMap.size()); i++; } else { int exist = cMap.get(c); // 清除 cur - exist之间的字符串 for (int j = lastClearIdx + 1; j <= exist; j++) { cMap.remove(chars[j]); } lastClearIdx = exist; } } return max; } // 思路3,但是直接利用string.charAt(),不转换成arr public static int lengthOfLongestSubstring3(String s) { if (s == null || s.length() == 0) { return 0; } int max = 0; int len = s.length(); int i = 0; // 已经清除的最后一个idx,初始时-1表示未清除任何字符 int lastClearIdx = -1; Map cMap = new HashMap<>(); while (i < len) { char c = s.charAt(i); // 不存在 if (!cMap.containsKey(c)) { cMap.put(c, i); max = Math.max(max, cMap.size()); i++; } else { int exist = cMap.get(c); // 清除 cur - exist之间的字符串 for (int j = lastClearIdx + 1; j <= exist; j++) { cMap.remove(s.charAt(j)); } lastClearIdx = exist; } } return max; } }
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖
  • 算法
    437 引用 • 254 回帖 • 24 关注

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 4 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 636 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    199 引用 • 543 回帖 • 2 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    13 引用 • 57 回帖 • 6 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 199 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 701 关注
  • OneNote
    1 引用 • 3 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 2 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 399 关注
  • Access
    1 引用 • 3 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 49 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 94 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    170 引用 • 315 回帖
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 316 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 543 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    239 引用 • 224 回帖 • 1 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 57 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 1 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    196 引用 • 291 回帖 • 373 关注
  • Visio
    1 引用 • 2 回帖 • 1 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    176 引用 • 3859 回帖
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    20 引用 • 7 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 501 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2040 回帖 • 1 关注
  • abitmean

    有点意思就行了

    33 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 638 关注