LeetCode 3090.每个字符最多出现两次的最长子字符串

题目链接

https://leetcode.cn/problems/maximum-length-substring-with-two-occurrences/

题目描述

给定一个字符串 s,找出满足每个字符最多出现两次的最长子字符串,并返回其长度。

示例

  • 输入:s = "aabba"
    • 输出:5
    • 解释:子字符串 "aabba" 中每个字符(ab)最多出现两次,且长度为 5。
  • 输入:s = "aaaa"
    • 输出:2
    • 解释:最长子字符串为 "aa",每个字符最多出现两次。

解法分析:滑动窗口 + 数组计数

核心思路

本题采用滑动窗口算法,通过左右指针维护一个有效区间,确保区间内每个字符的出现次数不超过 2 次。同时,利用长度固定的数组记录字符出现的频率,实现高效的计数与判断。

代码实现

class Solution:def maximumLengthSubstring(self, s: str) -> int:# 使用长度26的数组记录小写字母出现次数(假设输入仅包含小写字母)count = [0] * 26ans = left = 0for right in range(len(s)):# 计算当前字符的索引(a=0, b=1,...z=25)idx = ord(s[right]) - ord('a')count[idx] += 1  # 右指针字符计数+1# 当字符出现次数>2时,移动左指针收缩窗口while count[idx] > 2:left_idx = ord(s[left]) - ord('a')count[left_idx] -= 1  # 左指针字符计数-1left += 1            # 左指针右移# 更新最大窗口长度ans = max(ans, right - left + 1)return ans

关键逻辑解析

  1. 初始化

    • count:长度为 26 的数组,用于记录小写字母的出现次数,假设输入仅包含小写字母。数组下标 0 对应字符 a1 对应 b,以此类推。
    • ans:记录满足条件的最长子字符串长度,初始值为 0。
    • left:滑动窗口的左指针,初始值为 0。
  2. 右指针扩展

    • 使用 right 从左到右遍历字符串 s
    • 通过 ord(s[right]) - ord('a') 将字符转换为数组索引,对 count 数组中对应位置的计数加 1,表示当前字符出现次数增加。
  3. 左指针收缩

    • count[idx] > 2 时,说明当前字符在窗口内出现次数超过 2 次,需要收缩窗口。
    • 通过 ord(s[left]) - ord('a') 计算左指针指向字符的索引,将其在 count 数组中的计数减 1。
    • 左指针 left 右移一位,缩小窗口范围,直到当前字符出现次数不超过 2 次。
  4. 更新结果

    • 每次循环中,计算当前窗口的长度 right - left + 1,并与 ans 比较,取较大值更新 ans
    • 最终返回 ans,即满足条件的最长子字符串长度。

复杂度分析

  • 时间复杂度 O ( n ) O(n) O(n),其中 n n n 是字符串 s 的长度。左右指针最多各遍历字符串一次,每个字符最多被处理两次。
  • 空间复杂度 O ( 1 ) O(1) O(1),数组 count 的长度固定为 26,与输入字符串的长度无关。

优化点与注意事项

  1. 数组替代字典:使用固定长度的数组替代字典记录字符频率,避免哈希计算开销,在字符集固定(如小写字母)的场景下更高效。
  2. 字符集假设:当前代码假设输入仅包含小写字母,若字符集扩展(如包含大写字母、数字等),需要扩展数组长度或改用字典存储。
  3. 边界条件:代码默认输入字符串非空,题目保证 s.length ≥ 2,因此无需额外处理空字符串。

总结

本解法通过滑动窗口和数组计数的结合,在 O ( n ) O(n) O(n) 时间复杂度和 O ( 1 ) O(1) O(1) 空间复杂度内高效解决问题。其核心在于利用双指针动态维护有效区间,并通过数组快速判断字符出现频率。该思路可作为处理字符频率约束类问题的通用模板,适用于更多变种题型(如每个字符最多出现 k 次)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/87553.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/87553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用开源NVIDIA cuOpt加速决策优化

使用开源NVIDIA cuOpt加速决策优化 文章目录 使用开源NVIDIA cuOpt加速决策优化决策优化的现实挑战供应链优化的复杂性实时决策的挑战计算复杂性的挑战 NVIDIA cuOpt:GPU加速的决策优化解决方案cuOpt的核心技术架构支持的优化问题类型性能优势分析 实际应用案例&…

【JVM 09-垃圾回收】

垃圾回收 笔记记录 1. 如何判断对象可以回收1.1 引用计数法1.1.1 缺点 1.2 可达性分析算法1.2.1 可达分析、根对象1.2.2 优缺点 1.3 四种引用(强软弱虚)1.3.1 软引用的实际使用案例1.3.2 软引用-引用队列1.3.3 弱引用的实际使用案例 2. 垃圾回收算法2.1 标记清除算法2.2 标记整…

《二叉搜索树》

引言: 上次我们结束了类和对象的收尾,之后我们就要学习一些高级的数据结构,今天我们先来看一个数据结构-- 二叉搜索树。 一: 二叉搜索树的概念(性质) 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是…

【Redis】Sentinel哨兵

🛡️ 深入理解 Redis Sentinel:高可用架构的守护者 在实际开发中,我们常用 Redis 构建缓存系统或数据中间件。然而,主从复制虽然能实现数据同步,但无法自动故障转移(failover),这就…

Shell脚本应用及实战演练

文章目录 一、Shell脚本语言的基本结构1、Shell脚本的用途:2、 Shell脚本基本结构:3、 创建Shell脚本过程4、 脚本注释规范 二、Shell脚本语言的变量用法详解位置与预定义变量 三、 Shell字符串详解1、Shell字符串拼接2、Shell字符串截取3、 Shell的格式…

软件工程瀑布模型学习指南

软件工程瀑布模型学习指南 一、瀑布模型核心概念 1.1 定义与特点 瀑布模型是一种经典的软件开发流程,将项目划分为顺序性的阶段,每个阶段有明确的输入和输出,如同瀑布流水般单向推进。其特点包括: 阶段间具有明确的顺序性和依赖性强调文档驱动和阶段评审适合需求明确、稳…

获取gitlab上项目分支版本(二)

获取gitlab上项目分支版本_gitlab代码分支版本在哪-CSDN博客 原先写过一版,但是这次想更新一下项目的分支信息时,提示我 git服务器上的Python版本是2.7.3,这个错误表明当前Python环境中没有安装requests库,服务器也没有连接外网&…

主流防火墙策略绕过漏洞的修复方案与加固实践

主流防火墙策略绕过漏洞的修复方案与加固实践 流量关键点分析(攻击手法) 攻击者通过精心构造的TCP序列号攻击和恶意标志组合绕过防火墙DPI检测,核心手法如下: TCP连接建立(正常握手) 1049:客户…

泛微OAe9-后端二开常见数据库操作

泛微OAe9-后端二开常见数据库操作 文章目录 泛微OAe9-后端二开常见数据库操作一、RecordSet1 RecordSet 操作OA本身的表2 RecordSet 操作OA 本身的存储过程 二、RecordSetTrans三、RecordSetDataSource四、原生 jdbc 一、RecordSet RecordSet 适用于操作 OA 自己的库。OA 数据库…

【数据分析八:hypothesis testing】假设检验

本节我们讲述假设检验和抽样方法 有关假设检验的详细内容,可以参考我以往的博客 概率论与数理统计总复习_概率论与数理统计复习-CSDN博客文章浏览阅读1.5k次,点赞33次,收藏23次。中科大使用的教辅《概率论和数理统计》,带大家复…

AI免费工具:promptpilot、今天学点啥、中英文翻译

promptpilot 激发模型潜能,轻松优化 Prompt https://promptpilot.volcengine.com/startup 今天学点啥 https://metaso.cn/study 能生成网页和语音播报 中英文翻译 沉浸式翻译,浏览器插件,ai翻译

计算机网络学习笔记:TCP三报文握手、四报文挥手

文章目录 前言一、TCP三报文握手二、TCP四报文挥手三、TCP保活计时器 前言 TCP通信,通常需要经历三个阶段:三报文握手->发送,接收数据->四报文挥手。 一、TCP三报文握手 三报文握手处于TCP的连接建立阶段,主要解决了以下的…

kafka部署和基本操作

一、部署kafka 解压 tar xzvf kafka_2.12-3.9.1.tgz tar -zxf kafka_2.12-3.9.1.tgz 1.修改config/server.properties # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # …

Bootstrap 5学习教程,从入门到精通,Bootstrap 5 导航语法知识点及案例代码(17)

Bootstrap 5 导航语法知识点及案例代码 Bootstrap 5 提供了强大的导航组件,帮助开发者快速构建响应式且美观的导航栏。 一、Bootstrap 5 导航组件概述 Bootstrap 5 提供了多种导航组件,主要包括: 导航栏(Navbar)&am…

清除 docker 无用的 镜像/容器

清除 docker 无用的 镜像/容器 删除 <none> 的 docker 镜像 使用以下命令删除所有 的 Docker 镜像&#xff08;即悬空镜像 / dangling images&#xff09;&#xff1a; docker image prune -f这会自动删除所有没有 tag 的镜像&#xff08;&#xff09;&#xff0c;不会…

使用Charles抓包工具提升API调试与性能优化效率

在软件开发过程中&#xff0c;网络请求调试和性能优化往往成为开发者遇到的挑战&#xff0c;尤其是在进行API接口调试时。开发者需要确保网络请求的正确性、响应时间以及系统的整体性能。然而&#xff0c;传统的调试方法常常无法提供足够的细节来深入分析问题&#xff0c;进而影…

如何协调各项目关键节点的冲突与依赖

在多项目并行的环境下&#xff0c;关键节点间的冲突与依赖是导致项目延期、资源浪费和沟通误解的主要根源。要高效协调此类问题&#xff0c;企业应重点从建立透明的进度依赖图、使用项目管理工具对齐节点、推动跨部门协同机制入手。其中&#xff0c;通过Gantt图或关键路径法实现…

mongodb单节点改副本集模式

前一阵将三节点的副本集改成了单节点&#xff0c;但后面业务代码出现问题&#xff1a;无法使用事务&#xff0c;因为事务只有在副本集上能用&#xff0c;单节点无法使用&#xff0c;故需要改回副本集模式&#xff0c;而我目前仅有一台服务器&#xff0c;所以考虑在一台服务器上…

Android 修改了页面的xml布局,使用了databinding,这时候编译时需要用到apt吗

deepseek回答&#xff1a; 在 Android 开发中使用 DataBinding 时&#xff0c;不需要显式使用 apt&#xff08;Annotation Processing Tool&#xff09;。以下是详细说明&#xff1a; 1. DataBinding 的编译机制 DataBinding 是 Android Gradle 插件原生支持的功能&#xff…

服务器如何从http升级到https(nginx)

1.证书申请 可以到阿里云或者华为云去申请证书&#xff0c;申请完下载证书是个压缩包&#xff0c;然后解压 可以到到几个文件夹&#xff0c;找到 .Nginx 文件夹打开 会有两个文件&#xff0c;将这两个文件上传至nginx/conf/cert文件夹下&#xff08;cert需要手…