当前位置: 首页 > article >正文

无重复字符的最长子串(LeetCode 3)

文章目录

  • 1.问题描述
  • 2.难度等级
  • 3.热门指数
  • 4.解题思路
    • 方法一:暴力法
    • 方法二:滑动窗口
  • 参考文献

1.问题描述

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

s 由英文字母、数字、符号和空格组成。

示例 1:

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

示例 2:

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

示例 3:

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

2.难度等级

Medium。

3.热门指数

★★★★★

出题公司:阿里、腾讯、字节。

4.解题思路

方法一:暴力法

我们可以遍历字符串的所有字符,计算每个字符为起点的不含有重复字符的字串长度,记录到全局变量。

以示例 1 中的字符串 “abcabcbb” 为例,演示暴力法的求解过程。

以 (a)bcabcbb 开始的最长字符串为 (abc)abcbb
以 a(b)cabcbb 开始的最长字符串为 a(bca)bcbb
以 ab(c)abcbb 开始的最长字符串为 ab(cab)cbb
以 abc(a)bcbb 开始的最长字符串为 abc(abc)bb
以 abca(b)cbb 开始的最长字符串为 abca(bc)bb
以 abcab(c)bb 开始的最长字符串为 abcab(cb)b
以 abcabc(b)b 开始的最长字符串为 abcabc(b)b
以 abcabcb(b) 开始的最长字符串为 abcabcb(b)

所以最长子串长度为 3。

如何判断重复字符?

常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set 和 Golang 中的 map 等)。

时间复杂度: O ( n 2 ) O(n^2) O(n2),n 为字符串长度。

空间复杂度: 最好为 O(1),最坏为 O(n)。

方法二:滑动窗口

暴力法的求解过程,实际上存在不必要的检查。

以示例 1 中的字符串 “abcabcbb” 为例,演示暴力法的求解过程可优化的地方。

以 (a)bcabcbb 开始的最长字符串为 (abc)abcbb
以 a(b)cabcbb 开始的最长字符串为 a(bca)bcbb
以 ab(c)abcbb 开始的最长字符串为 ab(cab)cbb
以 abc(a)bcbb 开始的最长字符串为 abc(abc)bb

下面这一步是没有必要的,因为以 b 开始的不重复子串 bc 在上一个不重复子串内,长度肯定小于上一个不重复子串。
以 abca(b)cbb 开始的最长字符串为 abca(bc)bb

以 abcab(c)bb 开始的最长字符串为 abcab(cb)b

同理,下面这一步也是没有必要的。
以 abcabc(b)b 开始的最长字符串为 abcabc(b)b

以 abcabcb(b) 开始的最长字符串为 abcabcb(b)

在获取一个子串时,如果遇到了重复字符,那么获取下一个无重复字符的子串时,应该从重复字符的下一个字符开始。

将无重复字符的子串想象成一个滑动窗口,整个求解过程是移动滑动窗口的过程。

如何移动滑动窗口?

当出现重复字符时,我们只要把窗口内重复字符及其左边的元素移出就行了。

一直维持这样的窗口,直至窗口滑动到最后一个字符。记录最长的窗口长度,求出解!

时间复杂度: O(n),n 为字符串长度。

空间复杂度: 最好为 O(1),最坏为 O(n)。

下面以 Golang 为例,给出实现。

func lengthOfLongestSubstring(s string) int {
	var longest int
	m := make(map[rune]bool)
    var left int
	for _, c := range s {
		for m[c] {
			delete(m, rune(s[left]))
            left++
		}
        m[c] = true
        if len(m) > longest {
		    longest = len(m)
	    }
    }
	return longest
}

参考文献

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


http://www.kler.cn/a/163327.html

相关文章:

  • C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信
  • Visual Studio Code 端口转发功能详解
  • 【异质图学习】异构图神经网络中的自监督学习:基于语义强度和特征相似度的对比学习
  • 将 Docker 镜像保存到本地文件系统中
  • HTTPS通信和TCP通信有什么不一样
  • 订单分库分表
  • 记录一下Mac配置SpringBoot开发环境
  • “华为杯”研究生数学建模竞赛2016年-【华为杯】A题:无人机在抢险救灾中的优化运用(附获奖论文及MATLAB代码实现)
  • perf与火焰图-性能分析工具
  • IntelliJ IDEA使用Eval Reset
  • Unity使用打成图集的Sprite作为模型贴图使用的问题
  • ubuntu server 20.04 备份和恢复 系统 LTS
  • 小红书用户采集工具:掌握策略,轻松吸引潜在客户
  • 【flink番外篇】1、flink的23种常用算子介绍及详细示例(1)- map、flatmap和filter
  • 【链表Linked List】力扣-82 删除链表中的重复元素II
  • velocity-engine-core是什么?Velocity模板引擎的使用
  • pr抖音素材42个手机竖屏抖音视频转场特效PR剪辑模板
  • 浅谈5G基站节能及数字化管理解决方案的设计与应用-安科瑞 蒋静
  • 智慧城市是什么?为什么要建智慧城市?
  • 8_企业架构缓存中间件分布式memcached
  • 云原生系列1
  • 力扣(LeetCode)1038. 从二叉搜索树到更大和树(C++)
  • 卷积之后通道数为什么变了
  • java实现冒泡排序算法
  • 做题笔记:SQL Sever 方式做牛客SQL的题目--SQL156
  • 什么是Nginx反向代理?Nginx反向代理配置指南