- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
本文关键词:LeetCode,力扣,算法,算法题,字符串,双指针,刷题群
题目地址:https://leetcode.com/problems/longest-repeating-character-replacement/description/
Given a string that consists of only uppercase English letters, you can replace any letter in the string with another letter at most k times. Find the length of a longest substring containing all repeating letters you can get after performing the above operations.
Note: Both the string's length and k will not exceed 104.
Example 1:
Input:
s = "ABAB", k = 2
Output:
4
Explanation:
Replace the two 'A's with two 'B's or vice versa.
Example 2:
Input:
s = "AABABBA", k = 1
Output:
4
Explanation:
Replace the one 'A' in the middle with 'B' and form "AABBBBA".
The substring "BBBB" has the longest repeating letters, which is 4.
求一个字符串修改k个字符后,能够成的最长的相同字符组成的连续子序列。
首先需要区分两个概念:子串(子数组) 和 子序列。这两个名词经常在题目中出现,非常有必要加以区分。子串sub-string(子数组 sub-array)是连续的,而子序列 subsequence 可以不连续。
我读完今天这个题目之后,脑子里把题目转成了另外一个表达方式:求字符串中一个最长的区间,该区间内的出现次数较少的字符的个数不超过 k。
上面的表达方式跟题目是等价的,抽象成这种表达方式的好处是让我们知道这是一个区间题,求子区间经常使用的方法就是双指针。
《挑战程序设计竞赛》这本书中把双指针叫做「虫取法」,我觉得非常生动形象。因为双指针移动的过程和虫子爬动的过程非常像:前脚不动,把后脚移动过来;后脚不动,把前脚向前移动。
我分享一个双指针的模板,能解决大多数的双指针问题:
def findSubstring(s):
N = len(s) 数组/字符串长度
left, right = 0, 0 双指针,表示当前遍历的区间[left, right],闭区间
counter = collections.Counter() 用于统计 子数组/子区间 是否有效
res = 0 保存最大的满足题目要求的 子数组/子串 长度
while right < N: 当右边的指针没有搜索到 数组/字符串 的结尾
counter[s[right]] += 1 增加当前右边指针的数字/字符的计数
while 区间[left, right]不符合题意:# 此时需要一直移动左指针,直至找到一个符合题意的区间
counter[s[left]] -= 1 移动左指针前需要从counter中减少left位置字符的计数
left += 1 真正的移动左指针,注意不能跟上面一行代码写反
到 while 结束时,我们找到了一个符合题意要求的 子数组/子串
res = max(res, right - left + 1) 需要更新结果
right += 1 移动右指针,去探索新的区间
return res
1 2 3 4 5 6 7 8 9 10 11 12 13 14
简单介绍上面的模板,模板的思想是:以右指针作为驱动,拖着左指针向前走。右指针每次只移动一步,而左指针在内部 while 循环中每次可能移动多步。右指针是主动前移,探索未知的新区域;左指针是被迫移动,负责寻找满足题意的区间。
模板的整体思想是:
1、 定义两个指针left
和right
分别指向区间的开头和结尾,注意是闭区间;定义counter
用来统计该区间内的各个字符出现次数;
2、 第一重while
循环是为了判断right
指针的位置是否超出了数组边界;当right
每次到了新位置,需要增加right
指针的计数;
3、 第二重while
循环是让left
指针向右移动到[left,right]
区间符合题意的位置;当left
每次移动到了新位置,需要减少left
指针的计数;
4、 在第二重while
循环之后,成功找到了一个符合题意的[left,right]
区间,题目要求最大的区间长度,因此更新res
为max(res,当前区间的长度)
;
5、 right
指针每次向右移动一步,开始探索新的区间;
模板中为什么不把 counter
放在 while
循环内部呢?因为如果放在 while
内部每次新建一个 counter
变量,统计区间的字符出现次数的时间复杂度是 O(N)
;放在 while
外部,每次增加 right
指向的字符的计数、减少 left
指向的字符的计数的是时间复杂度是 O(1)
。这也是常见的统计区间问题时的技巧。类似的,如果我们要求一个区间的和的话,也可以用类似的思想去做。
今天的代码可以直接套用上面的双指针模板,内层的 while
循环中的判断条件该区间内出现次数较少的字符的出现次数是否大于 k
。如果大于 k
的话,说明该区间不符合题意,需要移动 left
指针直至符合题意为止。
如果理解了上面的双指针模板之后,我做了动图帮助理解。
使用Python2 写的代码如下。
class Solution(object):
def characterReplacement(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
N = len(s)
left, right = 0, 0 [left, right] 都包含
counter = collections.Counter()
res = 0
while right < N:
counter[s[right]] += 1
while right - left + 1 - counter.most_common(1)[0][1] > k:
counter[s[left]] -= 1
left += 1
res = max(res, right - left + 1)
right += 1
return res
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
DDKK.COM 弟弟快看-教程,程序员编程资料站,版权归原作者所有
本文经作者:负雪明烛 授权发布,任何组织或个人未经作者授权不得转发
我正在尝试编写一个名为 map-longest 的 Clojure 实用函数(感谢备用名称建议)。该函数将具有以下“签名”: (map-longest fun missing-value-seq c1
为什么我创建了一个重复的线程 我在阅读后创建了这个线程 Longest increasing subsequence with K exceptions allowed .我意识到提出问题的人并没有真
我正在编写一个 Sub 来识别 1 到 1000 之间最长的 Collatzs 序列。由于我刚刚开始学习 VBA,我想知道如何添加过程来计算每个序列的长度。 Sub Collatz() Dim i
我正在编写一个 Sub 来识别 1 到 1000 之间最长的 Collatzs 序列。由于我刚刚开始学习 VBA,我想知道如何添加过程来计算每个序列的长度。 Sub Collatz() Dim i
我正在尝试减去 CSV 中的两列以创建第三列“持续时间”结束时间 - 开始时间 每一行也对应一个用户 ID。 我可以创建一个仅包含“持续时间”列的 csv 文件,但我宁愿将其重定向回原始 csv。 例
我在 2018.04 玩这个最长的 token 匹配,但我认为最长的 token 不匹配: say 'aaaaaaaaa' ~~ m/ | a+? | a+ /; # 「a」
因此,按照规范规定最终用户/应用程序提供的给定变量(200 字节)的字节长度。 使用 python 字符串,字符串的最大字符长度是多少,满足 200 字节,因此我可以指定我的数据库字段的 max_le
我需要针对我们的Jenkins构建集群生成每周报告。报告之一是显示具有最长构建时间的作业列表。 我能想到的解决方案是解析每个从属服务器(也是主服务器)上的“构建历史”页面,对于作业的每个构建,都解析该
我正在构建一个 iOS 应用程序,它将流式传输最长为 15 秒的视频。我阅读了有关 HLS 的好文章,因此我一直在对片段大小为 5 秒的视频进行转码。如果视频的第一部分加载时间太长,那么我们可以在接下
docs for Perl 6 longest alternation in regexes punt to Synopsis 5记录 longest token matching 的规则.如果不同的
我是一名优秀的程序员,十分优秀!