算法练习题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

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

MySQL中删除重复数据SQL的三种写法

《MySQL中删除重复数据SQL的三种写法》:本文主要介绍MySQL中删除重复数据SQL的三种写法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录方法一:使用 left join + 子查询删除重复数据(推荐)方法二:创建临时表(需分多步执行,逻辑清晰,但会

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig