算法练习题07:无重复字符的最长子串

2024-09-02 07:36

本文主要是介绍算法练习题07:无重复字符的最长子串,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们可以使用 滑动窗口 的方法来解决这个问题。这是一种高效的算法,能在 O(n) 的时间复杂度内完成任务。以下是具体的解题思路:

1. 滑动窗口的概念

滑动窗口的想法是使用两个指针(通常称为左指针 i 和右指针 j)来表示一个窗口。这两个指针在字符串上滑动,以找到满足条件的子串。在这个问题中,我们的目标是找到最长的、没有重复字符的子串。

窗口的定义:窗口是由左指针 i 和右指针 j 所包围的子串 s[i:j],它包含 i 到 j-1 的字符。

窗口的移动:右指针 j 用于扩展窗口,左指针 i 用于缩小窗口。

2. 使用数据结构来检测重复字符

为了高效地检测一个字符是否已经在当前窗口中,我们使用一个 HashSet 数据结构。HashSet 允许我们在 O(1) 时间复杂度内判断一个字符是否存在,并且可以在 O(1) 时间内添加或移除字符。

3. 具体步骤
  1. 初始化

    • 定义一个 HashSet 来存储当前窗口内的字符。
    • 初始化两个指针 i 和 j,都指向字符串的开头(即 0)。
    • 初始化一个变量 maxLen 来记录最长无重复子串的长度。
  2. 遍历字符串

    • 使用 j 遍历整个字符串,将每个字符依次尝试添加到 HashSet 中。
    • 如果当前字符 s[j] 不在 HashSet 中:
      • 将其添加到 HashSet 中,表示扩展窗口。
      • 计算当前窗口的长度 j - i + 1,并更新 maxLen
    • 如果当前字符 s[j] 已经存在于 HashSet 中:
      • 说明遇到了重复字符,此时要通过移动左指针 i 来缩小窗口,直到移除重复的字符。
      • 移动左指针的过程中,同时从 HashSet 中移除对应的字符,直到可以将 s[j] 再次安全地添加到 HashSet 中。
  3. 更新结果

    • 每次右指针 j 向右移动时,计算当前窗口的长度,并更新 maxLen,以保证 maxLen 始终保持最长无重复子串的长度。
  4. 返回结果

    • 当右指针 j 遍历完整个字符串后,maxLen 就是最长无重复子串的长度。
class Solution {public int lengthOfLongestSubstring(String s) {HashSet<Character> set = new HashSet<>();int maxLen = 0;int i = 0, j = 0;int len = s.length();while (j < len) {if (!set.contains(s.charAt(j))) {set.add(s.charAt(j));j++;maxLen = Math.max(maxLen, j - i);} else {// 按顺序移除字符set.remove(s.charAt(i));i++;}}return maxLen;}
}

当右指针 j 遇到一个已经存在于 HashSet 中的字符时,我们需要移动左指针 i,从左侧开始逐个移除字符,直到移除重复的那个字符为止。这样可以确保 HashSet 中的字符总是唯一的。 

这篇关于算法练习题07:无重复字符的最长子串的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1129372

相关文章

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

Java如何用乘号来重复字符串的功能

《Java如何用乘号来重复字符串的功能》:本文主要介绍Java使用乘号来重复字符串的功能,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java乘号来重复字符串的功能1、利用循环2、使用StringBuilder3、采用 Java 11 引入的String.rep

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

idea报错java: 非法字符: ‘\ufeff‘的解决步骤以及说明

《idea报错java:非法字符:‘ufeff‘的解决步骤以及说明》:本文主要介绍idea报错java:非法字符:ufeff的解决步骤以及说明,文章详细解释了为什么在Java中会出现uf... 目录BOM是什么?1. BOM的作用2. 为什么会出现 \ufeff 错误?3. 如何解决 \ufeff 问题?最