LeetCode 最长重复子串的更换问题

news2024/11/26 20:37:49

在这里插入图片描述

LeetCode 最长重复子串的更换问题

在处理字符串问题时,我们经常会遇到一些具有挑战性的问题,比如今天的这个问题:给定一个字符串 s 和一个整数 k,我们的任务是找到可以通过最多更换 k 个字符来形成的最长重复子串的长度。

我的解决方案可能不是最快速、最有效或最简单的,但我希望通过这个过程深入理解相关的算法。

这个问题要求我们找到可以更换最多 k 个字符来形成重复子串的最长字符串。简单来说,就是允许我们改变字符串中的 k 个字符,使其变成另一个字符,从而创建一个重复的模式。

一种直观的方法是从长度为1的子串开始尝试,并逐步增加子串的长度,直到找到第一个不符合要求的子串。如果子串的长度为 n 且符合要求,那么长度为 n-1 的子串也必然符合要求。但是,这种方法的时间复杂度较高。

有没有更快的方法呢?我们注意到,通过连续检查长度为1、2、3等的子串,我们实际上是在按顺序检查子串的长度。这样的排序顺序让我们有机会使用二分搜索来加快搜索过程。

在这种情况下,我们如何应用二分搜索呢?首先,我们需要确定子串有效性的特征。问题的本质是找到一个子串,其中最常见的字符频率与子串长度之间的差值小于或等于 k。这个差值表示除了最常见字符之外的字符数量。如果这个差值小于或等于 k,我们就可以把这些字符全部更换为最常见的字符,从而形成一个只包含相同字符的子串。

假设子串的长度为 l,最常见的字符频率为 maxFreq。如果长度为 l 的子串有效,那么 l - maxFreq <= k 必然成立。如果长度为 l 的子串有效,那么长度小于 l 的所有子串也都有效。这就意味着,如果找到一个有效的长度 l,所有长度小于 l 的子串也都是有效的。

但是,如果长度为 l 的子串无效,即 l - maxFreq > k,我们能对长度为 l+1 的子串说什么呢?显然,l + 1 - maxFreq > l - maxFreq > k,这意味着如果长度为 l 的子串无效,那么所有长度大于 l 的子串也都无效。

借助这些信息,我们如何应用二分搜索呢?二分搜索通过设置两个边界 lohi 来定义搜索空间。搜索空间是所有可能的候选解的集合。我们将中间的元素与目标值进行比较,以确定目标值是在搜索空间的前半部分还是后半部分。基于这个比较,我们调整 lohi 来缩小搜索空间。这个过程一直持续到搜索空间中只剩下一个元素为止,这个元素就是我们要找的答案。

回到我们的问题,我们使用 lohi 来定义搜索空间的两端:lo 表示到目前为止已知的最长有效子串的长度,hi 表示一个比搜索空间更高的值。我们之所以称这两个事实为不变,是因为我们需要在每一轮搜索后维护它们。

为了缩小搜索空间,我们遵循以下步骤:

  1. 找到中点。
  2. 如果我们找到一个长度等于中点值的有效子串,那么所有长度小于中点的子串也都是有效的,但不能是最长的子串。我们知道的最长子串的长度是中点值。为了在保持不变的情况下缩小搜索空间,我们将 lo 移动到 mid。现在,lo 仍然指向到目前为止已知的最长有效子串的长度,而 hi 保持不变。
  3. 如果我们找不到长度等于中点值的有效子串,那么所有更长的子串也都无效。因此,最长子串的长度应该小于中点值。我们将搜索空间缩小到从 lomid - 1,通过将 hi 移动到 mid。现在 hi 指针比搜索空间高一个单位,而 lo 保持不变。
  4. 我们继续步骤2和3,直到 lohi 相邻。在这种情况下,lo 指向到目前为止已知的最长有效子串的长度,而 hi 指向一个比搜索空间更高的值。因此,搜索空间中只剩下一个值 lo,这可能是最长子串的长度。这就是我们要找的答案。

以下是实现这个算法的JavaScript代码:

function characterReplacement(s: string, k: number): number {
    let lo = k, hi = s.length + 1;

    while(lo < hi - 1) {
        const mid = Math.floor((lo + hi)/2);
        if(isValidLength(mid)) {
            lo = mid;
        }
        else {
            hi = mid;
        }
    }

    return lo;

    function isValidLength(l:number):boolean {
        const hashTB:Record<string, number> = {};

        let start = 0, maxFreq = 0;

        for(let end = 0; end < s.length; end++) {
            if(!hashTB[s[end]]) hashTB[s[end]] = 1;
            else hashTB[s[end]]++;
            if(end - start + 1 > l) {
                hashTB[s[start]]--;
                start++;
            }
            if(maxFreq < hashTB[s[end]]) {
                maxFreq = hashTB[s[end]];
            }
            if(l - maxFreq <= k) return true;
        }

        return false;
    }
}

这段代码通过二分搜索和有效性验证函数 isValidLength 来确定最长重复子串的长度。这个过程不仅提高了解决问题的效率,还加深了我们对算法和数据结构的理解。

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

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

相关文章

【HDFS存储】Java语言实现

Hadoop生态系统中包含多种与其相关联的技术应用&#xff0c;主要包括但不限于HDFS HDFS&#xff08;Hadoop Distributed File System&#xff09;&#xff1a;作为一个高度可靠、高吞吐量的分布式文件系统&#xff0c;它是Hadoop核心技术之一&#xff0c;用于存储海量数据。 J…

如何停止 Win11 自动更新?如何彻底关闭 Windows 更新呢?

如何停止 Win11 自动更新&#xff1f;如何彻底关闭 Windows 更新呢&#xff1f; 段子手168 我们在使用电脑时&#xff0c;有时并不需要 windows 频繁更新系统&#xff0c; 这样可能会使你的 C 盘突然爆满或者系统启动缓慢&#xff0c; 那么如何彻底关闭 Windows 更新呢&#…

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏,又增加了哔哩哔哩搜索和必应搜索

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏&#xff0c;又增加了哔哩哔哩搜索和必应搜索. <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"…

ETL工具-nifi干货系列 第九讲 处理器EvaluateJsonPath,根据JsonPath提取字段

1、其实这一节课本来按照计划一起学习RouteOnAttribute处理器&#xff08;相当于java中的ifelse&#xff0c;switch case 控制语句&#xff09;&#xff0c;但是在学习的过程中遇到了一些问题。RouteOnAttribute 需要依赖处理器EvaluateJsonPath&#xff0c;所以本节课我们一起…

ESP8266开发

1esp8266Wifi连接,通过手机控制点灯 1.下载Arduino,编程 2.下载blinker手机APP。 3.下载blinker库。https://arduino.me/s/blinker-arduino?aid=711 4.打开编程工具 Arduino,加载blinker库 5. 打开库里面的例程,基于例程开发。 blinker-library-0.3.10230510\blinker-…

JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)

目录 BigDecimal BigDecimal的常见构造器、常用方法 用法示例 使用规范 在进行浮点型运算时&#xff0c;直接使用“ - * / ”可能会出现运算结果失真&#xff0c;例如&#xff1a; System.out.println(0.1 0.2); System.out.println(1.0 - 0.32); System.out.println(1.…

【Ubuntu】 Github Readme导入GIF

1.工具安装 我们使用 ffmpeg 软件来完成转换工作1.1 安装命令 sudo add-apt-repository ppa:jonathonf/ffmpeg-3sudo apt-get updatesudo apt-get install ffmpeg1.2 转换命令 &#xff08;1&#xff09;直接转换命令&#xff1a; ffmpeg -i out.mp4 out.gif(2) 带参数命令&…

哨兵-1A与DInSAR技术监测尼泊尔地震前后地表形变

2015年4月25号&#xff0c;尼泊尔发生里氏7.8级地震&#xff0c;超过5000人伤亡和几百万人受到影响。大量的卫星影像支持地震救援。地理学家利用卫星影像量测地震对陆地的影响。 Sentinel-1A是欧洲委员会发起的哥白尼环境监测计划中的第一颗卫星。可获取全天候的数据&#xff0…

大模型+交通治理,高德地图“评诊治”系统迎来全新升级

近日&#xff0c;由中国道路交通安全协会主办的第十四届中国国际道路交通安全产品博览会暨公安交警警用装备展(以下简称交博会)在厦门国际会展中心开幕&#xff0c;会上高德地图发布了全新升级的城市交通“评诊治”智能决策SaaS系统&#xff0c;以助力城市交通的可持续、精细化…

水利自动化控制系统平台介绍

水利自动化控制系统平台介绍 在当今社会&#xff0c;水资源的管理和保护日益成为全球关注的重要议题。随着科技的进步和信息化的发展&#xff0c;水利监测系统作为一种集成了现代信息技术、自动化控制技术以及环境监测技术的综合性平台&#xff0c;正在逐步改变传统的水利管理模…

Oracle 常用命令总结

文章目录 一、数据库启动 & 关闭&查看1、启动数据库2、关闭数据库3、连接数据库4、查看数据库名5、查看实例 二、用户1、创建用户2、重置密码3、账户解锁4、账号赋权5、账户撤销权限6、删除用户7、查询所有用户&#xff08;DBA账号执行&#xff09;8、查看当前用户连接…

卫星影像联合无人机实现农业保险全生命周期监管监测

随着科技的进步&#xff0c;农业保险监管系统的发展日新月异。特别是近年来&#xff0c;随着卫星技术与无人机技术的结合&#xff0c;为农业保险监管系统带来了前所未有的革新。本文将深入探讨如何利用卫星与无人机方案构建高效的农业保险监管系统&#xff0c;并结合实例进行说…

面试经典算法系列之二叉树3 -- 二叉树的层序遍历

面试经典算法18 - 二叉树的层序遍历 LeetCode.102 公众号&#xff1a;阿Q技术站 问题描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;roo…

虚拟机中,IP地址查询失败怎么办

有时候ifconfig查出来的地址是下面这样&#xff0c;只有ipv6 只需要运行下面这两条命令&#xff0c;再次查询即可成功&#xff01; systemctl stop NetworkManagersystemctl start network.service

Python如何安装第三方模块

cmd窗口中使用pip install命令安装 1、键盘按下win R&#xff0c;然后在输入框中输入cmd&#xff0c;回车&#xff0c;就打开了cmd窗口。 下图的运行框会出现到屏幕左下角。 2、输入下面的命令&#xff0c;回车即可。 pip install xxx # xxx为要安装的模块名 如图所示&…

RabbitMQ消息模型之Simple消息模型

simple消息模型 生产者 package com.example.demo02.mq.simple;import com.example.demo02.mq.util.ConnectionUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection;import java.io.IOException;/*** author Allen* 4/10/2024 8:07 PM* versi…

【论文阅读笔记】Head-Free Lightweight Semantic Segmentation with Linear Transformer

莫名地这篇论文我特别难理解&#xff0c;配合代码也食用不了 1.论文介绍 Head-Free Lightweight Semantic Segmentation with Linear Transformer 基于线性Transformer的无头轻量级语义分割 2023年 AAAI Paper Code 2.摘要 现有的语义分割工作主要集中在设计有效的解码器&am…

MATLAB GUI图形化界面设计计算器

MATLAB GUI界面设计教程可以帮助用户创建交互式的图形用户界面&#xff0c;以简化与MATLAB程序的交互过程。以下是一个简化的教程&#xff0c;指导你如何进行MATLAB GUI界面设计&#xff1a; 1. 启动GUIDE或App Designer GUIDE&#xff1a;在MATLAB命令窗口中输入guide命令&a…

锐化空间滤波器--二阶微分图像增强(提高清晰度的另一种方式)

书上一阶微分的定义可以理解&#xff0c;毕竟这里不死数学上的曲线的概念&#xff0c;而是像素点上的曲线。所以&#xff0c;不同于数学的严格单调递增曲线的导数是大于等于零&#xff0c;这里的严格单调递增曲线&#xff0c;只能是大于零。 至于二阶微分的定义&#xff0c;就…

Scala实战:打印九九表

本次实战的目标是使用不同的方法实现打印九九表的功能。我们将通过四种不同的方法来实现这个目标&#xff0c;并在day02子包中创建相应的对象。 方法一&#xff1a;双重循环 我们将使用双重循环来实现九九表的打印。在NineNineTable01对象中&#xff0c;我们使用两个嵌套的fo…