LeetCode 2272.最大波动的子字符串:转为多次的最大子数组和 - 一步步思考推导
【LetMeFly】2272.最大波动的子字符串:转为多次的最大子数组和 - 一步步思考推导
力扣题目链接:https://leetcode.cn/problems/substring-with-largest-variance/
字符串的 波动 定义为子字符串中出现次数 最多 的字符次数与出现次数 最少 的字符次数之差。
给你一个字符串 s ,它只包含小写英文字母。请你返回 s 里所有 子字符串的 最大波动 值。
子字符串 是一个字符串的一段连续字符序列。
示例 1:
输入:s = "aababbb" 输出:3 解释: 所有可能的波动值和它们对应的子字符串如以下所示: - 波动值为 0 的子字符串:"a" ,"aa" ,"ab" ,"abab" ,"aababb" ,"ba" ,"b" ,"bb" 和 "bbb" 。 - 波动值为 1 的子字符串:"aab" ,"aba" ,"abb" ,"aabab" ,"ababb" ,"aababbb" 和 "bab" 。 - 波动值为 2 的子字符串:"aaba" ,"ababbb" ,"abbb" 和 "babb" 。 - 波动值为 3 的子字符串 "babbb" 。 所以,最大可能波动值为 3 。
示例 2:
输入:s = "abcde" 输出:0 解释: s 中没有字母出现超过 1 次,所以 s 中每个子字符串的波动值都是 0 。
提示:
1 <= s.length <= 104s只包含小写英文字母。
解题方法:动态规划
做本题之前推荐先做一下53. 最大子数组和:
一个数组中元素有正有负,如何求其非空子数组和的最大值呢?
遍历数组并使用一个变量 c n t cnt cnt统计即可。
对于当前元素a,可以选择在前面子数组的基础上加上这个元素( c n t + a cnt + a cnt+a),也可以选择丢弃前面子数组而从这个元素重新开始( a a a)。
因此有状态转移方程 c n t = max ( c n t + a , a ) cnt = \max(cnt + a, a) cnt=max(cnt+a,a)。
本题如何转为多次的“最大子数组”呢?本题的子数组只需要考虑出现次数最多和出现次数最少的两个元素,因此我直接两层循环枚举所有的“最多元素a”和“最少元素b”不就行了吗?
假设出现次数最多的元素是a,出现次数最少的元素是b。因为我们最终求的是 c o u n t ( a ) − c o u n t ( b ) count(a) - count(b) count(a)−count(b),所以我们可以将a赋值为1,将b赋值为-1,其他元素直接无视(或赋值为0)。
之后按照“最大子数组和”的方式求解,是不是就可以了?
不可以,因为“最多次数的a减去最少次数的b”的前提是“子数组中出现了b”。若子数组中全是a,那么出现次数最少的元素并非0次,而是同样为a次。也就是说,我们还需要想办法保证子数组中出现了b。
“最大子数组和”我们使用了一个变量cnt,本题我们可以使用两个变量 m a y N o B mayNoB mayNoB和 h a s B hasB hasB,分别表示子数组中可能不包含b和子数组中一定包含b时的“最大波动”。
因为mayNoB代表的子数组可以出现B也可以不出现B,所以mayNoB就和“最大子数组和”一样,无脑 m a y N o B = max ( m a y N o B + t , t ) mayNoB = \max(mayNoB + t, t) mayNoB=max(mayNoB+t,t)即可( t t t是字符的映射值 1 1 1或者 − 1 -1 −1或者 0 0 0)。
但是hasB就比较有意思了,它要求子数组中必须有b,怎么办呢?也很好说,把hasB的初始值定义为“无穷小”就好了。
- 若当前元素为b,则 h a s B = m a y N o B hasB = mayNoB hasB=mayNoB,因为 m a y N o B mayNoB mayNoB一旦包含当前元素b就一定 h a s B hasB hasB了(其实是 h a s B = m a x ( h a s B , m a y N o B ) hasB = max(hasB, mayNoB) hasB=max(hasB,mayNoB),但由于“可能不包含b”一定不小于“必须包含b”,所以可以直接简写为 h a s B = m a y N o B hasB=mayNoB hasB=mayNoB)
- 若当前元素为a,则 h a s B + = 1 hasB += 1 hasB+=1(若从未出现过元素b,则hasB即使加一也仍是无穷小,不影响后续答案的更新)
更新答案 a n s = m a x ( a n s , h a s B ) ans = max(ans, hasB) ans=max(ans,hasB)
- 时间复杂度 O ( l e n ( s ) × C 2 ) O(len(s)\times C^2) O(len(s)×C2),其中 C = 26 C=26 C=26
- 空间复杂度 O ( 1 ) O(1) O(1)
AC代码
C++
/** @Author: LetMeFly* @Date: 2025-03-16 10:43:25* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-03-16 11:03:26*/
#ifdef _WIN32
#include "_[1,2]toVector.h"
#endif#ifdef FirstTry // WA - 例如baa,一个变量会导致不选b,而只有aa虽然cnt比较大但不一定最优
class Solution {
public:int largestVariance(string s) {int ans = 0;for (int i = 0; i < 26; i++) {char a = i + 'a';for (int j = 0; j < 26; j++) {char b = j + 'a';int cnt = 0;bool hasB = false;for (char c : s) {if (c == a) {cnt++;} else if (c == b) {// cnt = max(cnt - 1, 0);if (cnt - 1 >= 0) {cnt--;hasB = true;} else {cnt = 0;hasB = false;}}if (hasB) {ans = max(ans, cnt);}}// printf("a = %c, b = %c, ans = %d\n", a, b, ans);}}return ans;}
};
#else // FirstTry
// SecondTry
class Solution {
public:int largestVariance(string s) {int ans = 0;for (int i = 0; i < 26; i++) {char a = i + 'a';for (int j = 0; j < 26; j++) {char b = j + 'a';int mayNoB = 0, hasB = -10000000;for (char c : s) {if (c == a) {mayNoB = max(mayNoB + 1, 1);hasB++;} else if (c == b) {mayNoB = max(mayNoB - 1, -1);hasB = mayNoB;}ans = max(ans, hasB);}}}return ans;}
};
#endif // FirstTry
Python
'''
Author: LetMeFly
Date: 2025-03-16 11:06:25
LastEditors: LetMeFly.xyz
LastEditTime: 2025-03-16 11:09:05
'''
class Solution:def largestVariance(self, s: str) -> int:ans = 0for i in range(26):a = chr(i + ord('a'))for j in range(26):b = chr(j + ord('a'))mayNoB, hasB = 0, -100000for c in s:if c == a:mayNoB = max(mayNoB + 1, 1)hasB += 1elif c == b:mayNoB = max(mayNoB - 1, -1)hasB = mayNoBans = max(ans, hasB)return ans
Java
/** @Author: LetMeFly* @Date: 2025-03-16 11:09:39* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-03-16 11:13:27*/
class Solution {public int largestVariance(String s) {int ans = 0;for (int i = 0; i < 26; i++) {char a = (char)(i + 'a');for (int j = 0; j < 26; j++) {char b = (char)(j + 'a');int mayNoB = 0, hasB = -10000000;for (char c : s.toCharArray()) {if (c == a) {mayNoB = Math.max(mayNoB + 1, 1);hasB++;} else if (c == b) {mayNoB = Math.max(mayNoB - 1, -1);hasB = mayNoB;}ans = Math.max(ans, hasB);}}}return ans;}
}
Go
/** @Author: LetMeFly* @Date: 2025-03-16 11:14:38* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-03-16 11:18:01*/
package mainfunc largestVariance(s string) (ans int) {for i := byte(0); i < 26; i++ {a := i + 'a'for j := byte(0); j < 26; j++ {b := j + 'a'mayNoB, hasB := 0, -10000000for _, c := range s {if byte(c) == a {mayNoB = max(mayNoB + 1, 1)hasB++} else if byte(c) == b {mayNoB = max(mayNoB - 1, -1)hasB = mayNoB}ans = max(ans, hasB)}}}return
}
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源
相关文章:
LeetCode 2272.最大波动的子字符串:转为多次的最大子数组和 - 一步步思考推导
【LetMeFly】2272.最大波动的子字符串:转为多次的最大子数组和 - 一步步思考推导 力扣题目链接:https://leetcode.cn/problems/substring-with-largest-variance/ 字符串的 波动 定义为子字符串中出现次数 最多 的字符次数与出现次数 最少 的字符次数之…...
火语言RPA--列表项内容设置
【组件功能】:设置列表项内容 配置预览 配置说明 索引项位置支持T或# 列表对象待修改内容的索引位置。 内容值 支持T或# 默认FLOW输入项 修改的内容值。 示例 对象修改 描述 列表对象索引为0的数据修改为A字符串,并打印修改结果。 配置 输出结…...
1.Qt SDK 的下载和安装
1Qt 下载官⽹: http://download.qt.io/archive/qt/ 2版本自行选择 3下载对应版本的.exe文件 4下载包下载完成 5双击.exe文件,默认下一步,要注册一个qt的账户 6记住程序安装的位置,后面要配置环境变量 7勾3个(组件自行…...
嵌入式系统中的Board Support Package (BSP)详解:以Xilinx Zynq为例
嵌入式系统中的Board Support Package (BSP)详解:以Xilinx Zynq为例 引言 在嵌入式系统开发中,硬件与软件的无缝集成至关重要。Board Support Package (BSP) 作为连接硬件和操作系统的桥梁,在这一过程中扮演着核心角色。本文将深入探讨BSP的…...
Spring Boot 定时任务以及异步任务的实现
一、定时任务 在 Spring Boot 中,实现定时任务非常简单,主要通过 Scheduled 注解和 TaskScheduler 接口来实现。以下是实现定时任务的详细步骤和方法: 启用定时任务支持 在 Spring Boot 应用中,首先需要启用定时任务支持。可以通…...
Vue 生命周期详解:从创建到销毁的全过程
Vue.js 是一个流行的前端框架,它通过组件化的方式帮助开发者构建用户界面。在 Vue 中,每个组件实例都有其生命周期,从创建、挂载、更新到销毁,Vue 提供了一系列的生命周期钩子函数,允许我们在组件的不同阶段执行自定义…...
【ASMbits--常用算术运算指令】
ASMbits--常用算术运算指令 1 基本运算算术指令--最基础1.1 加法和减法1.2 移位操作1.3 乘法 2 practice2.1 编写invert(int n)2.2 编写judge_odd(int n)2.3 计算绝对值abs(int n)2.4 add(int n1, int n2)函数2.4 shift寄存器2.5 sihft ath right2.6 shift left 在ARMv7汇编中&…...
计算机基础:二进制基础12,十进制数转换为十六进制
专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏,故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 (一)WIn32 专栏导航 上一篇:计算机基础:二进制基础11,十六进制的位基…...
SpringCloud系列教程(十四):Sentinel持久化
Sentinel之前已经搭建和应用成功了,但是它有一个很大的缺点就是官方没有提供持久化的方案,从项目源码上看感觉这款工具也没有完成的太好,所以需要我们去对它进行二次开发。要补充的功能大概如下: 1、将Sentinel接入nacos中&#…...
Slider,InputField,Scroll View,Scrollbar及Layout组件
Slider组件 Fill Rect:填充滑动条选中区域的背景图部分 Handle Rect:滑动条的球 Direction:滑动条的滑动方向 Min Value:起始位置的数值(浮点数) Max Value:结束位置的数值(浮点数) Whole Numbers:必须为整数(布尔…...
ollama注册自定义模型(GGUF格式)
文章目录 ollama注册自定义模型(GGUF格式)下载模型注册模型(GGUF格式) ollama注册自定义模型(GGUF格式) 需要全程开启ollama nohup ollama serve > ollama.log 2>&1 &需要注意,尽管手动下载的GGUF格式模…...
【算法】 区间合并(附蓝桥杯真题) python
步骤 1.先将所有区间按左端点排序 2.从前往后扫一遍,维护当前正在合并的区间[st, ed] 3.依次检查每个区间[l, r], 若 l > ed,将[st, ed]加入 ans , 更新st l,ed r 若 l < ed ,更新ed max(ed, r) 时间复杂度 O(nlogn) 模板 https:/…...
关于重构分析查询界面的思考(未完)
业务系统里,查询界面很常见,数据分析场景需求普遍而迫切,而新的技术也在不断出现,很有必要重构分析查询界面。 查询筛选 为了尽可能从数据中发现,需要尽可能地将查询条件添加进来,可这样,查询…...
机器人技能列表
一、机器人制作基础入门 (一)机器人概述 1.机器人的定义与分类 2.机器人的发展历程与现状 3.机器人在各领域的应用案例 (二)必备工具与材料 4.常用电子工具介绍(万用表、电烙铁等) 5.机械加工工具&…...
五大基础算法——分治算法
分治算法 是一种通过将问题分解为多个规模较小的子问题,递归解决子问题,然后将子问题的解合并为原问题解的算法思想。它通常包含三个步骤:分解(Divide)、解决(Conquer) 和 合并(Comb…...
HarmonyOS NEXT 声明式UI语法学习笔记-创建自定义组件
基础语法概述 ArkTS的基本组成 装饰器:用于装饰类、结构、方法以及变量,并赋予其特殊含义。如上图都是装饰器,Component表示自定义组件,Entry表示表示自定义组件的入口组件,State表示组件中的状态变量,当状…...
补充二分LIS
B3637 最长上升子序列 题目描述 这是一个简单的动规板子题。 给出一个由 n ( n ≤ 5000 ) n(n\le 5000) n(n≤5000) 个不超过 1 0 6 10^6 106 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。 最长上升子序列是指,从原序列中按顺序取出一些数字排…...
用户模块——握手验证
1. 引言 在现代 Web 应用中,WebSocket 以其全双工通信、低延迟、减少 HTTP 开销等优势,被广泛应用于即时通讯、在线游戏、实时数据推送等场景。然而,在涉及用户认证时,WebSocket 存在一个常见问题——每次刷新页面都会重新建立 We…...
97.HarmonyOS NEXT跑马灯组件教程:基础概念与架构设计
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT跑马灯组件教程:基础概念与架构设计 1. 跑马灯组件概述 跑马灯(Marquee)是一种常见的UI组件&a…...
81.HarmonyOS NEXT 状态管理与响应式编程:@Observed深度解析
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT 状态管理与响应式编程:Observed深度解析 文章目录 HarmonyOS NEXT 状态管理与响应式编程:Observed深度解析…...
【Agent】OpenManus-Agent架构详细分析
各组件详细设计见: BaseAgent:BaseAgentReActAgent:ReActAgentToolCallAgent:ToolCallAgent具体Agent实现:具体AgentMemory数据结构:Memory 1. 智能体层次结构 OpenManus 采用了一个多层次的智能体继承结…...
股指期货有卖不出去的时候吗?
在股指期货的交易世界里,很多人都有这样的疑问:股指期货会不会有卖不出去的时候呢?答案是会的,下面咱们就来详细唠唠为啥会出现这种情况。 市场极端行情下难以卖出 1.跌停限制:股指期货和股票一样,也有涨…...
前端Html5 Canvas面试题及参考答案
目录 Canvas 元素的默认尺寸是多少?如何正确设置其宽高以避免图像拉伸? 如何获取 Canvas 的 2D 上下文对象?3D 上下文支持哪些技术? canvas.width 与 canvas.style.width 的区别是什么? Canvas 支持的图像格式有哪些?如何将 Canvas 转换为 Base64 图片? Canvas 中如…...
【ES6】03-Set + Map
本文介绍两种集合 set map 的操作和方法。 目录 1. Set 1.1 set基本使用 1.2 add 1.3 delete 1.4 has 1.5 size 1.6 set转换为数组 1.7 拓展运算符 1.8 for...of 1.9 forEach 1.10 set给数组去重 2. Map 2.1 创建map集合 2.2 set添加元素 2.3 delete删除元素 …...
Java缓存String(字符串常量池)、Integer (-128 到 127 )
对问题的解释 1. “字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table” 的含义 这句话可以从以下几个方面理解: (1) 字符串常量池的存储内容 直接引用:字符串常量池中存储的是指向实际 Stri…...
消息队列的特性与使用场景:Kafka、ActiveMQ、RabbitMQ与RocketMQ的深度剖析
在分布式系统和微服务架构中,消息队列是实现服务间通信和解耦的核心组件。Kafka、ActiveMQ、RabbitMQ和RocketMQ是当前最受欢迎的消息队列解决方案,它们各自具有独特的特性和适用场景。本文将从特性和使用场景两个维度进行对比分析,帮助读者更…...
开发、科研、日常办公工具汇总(自用,持续更新)
主要记录汇总一下自己平常会用到的网站工具,方便查阅。 update:2025/2/11(开发网站补一下) update:2025/2/21(补充一些AI工具,刚好在做AI视频相关工作) update:2025/3/7&…...
解决VueI18n使用浏览器插件翻译后,切换国际化失效的问题
问题复现 在使用Vue-i18n对页面进行国际化的时候,使用浏览器翻译插件(如腾讯翻译)后,切换国际化语言,随后当我们关闭浏览器翻译插件后,再次切换国际化语言,原来被翻译的文字无法正确切换 出现…...
HTML5 drag API实现列表拖拽排序
拖拽API(Drag and Drop API)是HTML5提供的一组功能,使得在网页上实现拖放操作变得更加简单和强大。这个API允许开发者为网页元素添加拖拽功能,用户可以通过鼠标将元素拖动并放置到指定的目标区域。 事件类型 dragstart࿱…...
改变一生的思维模型【11】升维
升维思维模型:突破认知局限的破局法则 一、定义与核心逻辑 升维思维是通过增加分析维度,将问题投射到更高认知层次寻找解决方案的思考方式。其本质是跳出原有竞争维度,在更广阔的空间重构游戏规则。核心逻辑在于:当低维战场陷入…...
