424. 替换后的最长重复字符

题目:

给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

注意:
字符串长度 和 不会超过 104。

示例 1:

输入:
s = "ABAB", k = 2

输出:
4

解释:
用两个‘A‘替换为两个‘B‘,反之亦然。

示例 2:

输入:
s = "AABABBA", k = 1

输出:
4

解释:
将中间的一个‘A‘替换为‘B‘,字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。

解答:

开始没想到滑动窗口,用dfs做了半天,第20几个用例答案不对,查错也查不出来。

由于题目是问最长子串,这种题目动态规划或者滑动窗口需要着重考虑一下,因为都是当前状态都是和之前相邻的状态有关。


1.先固定左边界,右边界一直右移,直到当前区间内的需要替换的字母数大于k。

2.之后左边界右移,直到该区间需要替换的字母数小于等于k。重复1步骤。

问题是怎么找出某个区间内需要替换的字母数。

答案是用一个memo数组记录各字母在当前区间内的出现次数,出现最多的,我们认为它就是主要字母,其他字母都替换为它。这样总的替换次数是最少的。(其实就是贪心。)

(我之前妈蛋就是这里没想明白怎么找,结果用dfs遍历所有可能,太菜了)

可行的代码:

 1 class Solution {
 2 public:
 3     int characterReplacement(string s, int k) {
 4         int n=s.size();
 5         if(n==0){return 0;}
 6         int le=0,ri=0,max_cnt=0;
 7         int res=1;
 8         vector<int> cnt(26,0);
 9         while(ri<n){
10             cnt[s[ri]-‘A‘]+=1;
11             max_cnt=*max_element(cnt.begin(),cnt.end());
12             while(ri-le+1-max_cnt>k){
13                 cnt[s[le]-‘A‘]-=1;
14                 ++le;
15                 max_cnt=*max_element(cnt.begin(),cnt.end());
16             }
17             res=max(res,ri-le+1);
18             ++ri;
19         }
20         return res;
21     }
22 };

这个写法是对的,但是还有更优解。就是每次只有右边界更新的时候,max_cnt才进行更新。

左边界右移的时候不更新。

我自己也不是特别理解原理,只能贴一个解释:

这里有个优化,不需要每次都去重新更新max_count。比如说"AAABCDEDFG" k=2,这个case,一开始A出现3次,max_count=3,但是当指针移到D时发现不行了,要移动left指针了。此时count[‘A‘]-=1,但是不需要把max_count更新为2。为什么呢? 因为根据我们的算法,当max_count和k一定时,区间最大长度也就定了。当我们找到一个max_count之后,我们就能说我们找到了一个长度为d=max_count+k的合法区间,所以最终答案一定不小于d。所以,当发现继续向右扩展right不合法的时候,我们不需要不断地右移left,只需要保持区间长度为d向右滑动即可。如果有某个合法区间大于d,一定在某个时刻存在count[t]+1>max_count,这时再去更新max_count即可。

链接:https://leetcode-cn.com/problems/longest-repeating-character-replacement/comments/69360

代码优化为:

 1 class Solution {
 2 public:
 3     int characterReplacement(string s, int k) {
 4         int n=s.size();
 5         if(n==0){return 0;}
 6         int le=0,ri=0,max_cnt=0;
 7         int res=1;
 8         vector<int> cnt(26,0);
 9         while(ri<n){
10             cnt[s[ri]-‘A‘]+=1;
11             max_cnt=max(max_cnt,cnt[s[ri]-‘A‘]);
12             while(ri-le+1-max_cnt>k){
13                 cnt[s[le]-‘A‘]-=1;
14                 ++le;
15             }
16             res=max(res,ri-le+1);
17             ++ri;
18         }
19         return res;
20     }
21 };

原文地址:https://www.cnblogs.com/FdWzy/p/12423970.html

时间: 2024-10-31 20:23:46

424. 替换后的最长重复字符的相关文章

[Swift]LeetCode424. 替换后的最长重复字符 | Longest Repeating Character Replacement

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 abo

leetcode424 替换后的最长重复字符 java题解

本题是比较典型的滑动窗口问题 这类问题一般通过一个滑动窗口就能在O(N)的时间复杂度下求解 本题可以先退化成考虑K=0的情况,此时题目就变成了求解字符串中最长连续子串长度问题了 我们先可以通过这个特例先了解一下滑动窗口的求解过程 上图的求解过程展示中,窗口从左至右不断扩张/滑动,当窗口触达字符串末尾字符时,运算结束,窗口的宽度为最终结果.初始窗口的宽度为1,我们不断的通过向当前窗口覆盖的子串后面追加一个字符看是否能满足我们的要求,如果满足窗口扩张,如果不满足,窗口向右滑动. 当K>0时,子串的条

[LeetCode] Longest Repeating Character Replacement 最长重复字符置换

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 abo

查找字符串中最长重复字符的子串

temppos:记录子字符串开始的下标 list:存放重复的子字符串 public class RepeatString { private static void longestdupString(String s) { if (s == null || s.length() == 0) { return; } char temp = s.charAt(0); int temppos = 0; List<String> list = new ArrayList<String>()

No.3. 无重复字符的最长子串

3. 无重复字符的最长子串 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度.就是说,找一个最长的子串,这个子串没有重复字符 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew"

Leetcode3---&gt;无重复字符的最长子串长度

题目:给定一个字符串string,找出string中无重复字符的最长子串. 举例: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length of 1. Given "pwwkew", the answer is "wke"

符串的最长无重复字符的子串长度

题目描述: 对于一个字符串,请设计一个高效算法,找到字符串的最长无重复字符的子串长度. 给定一个字符串A及它的长度n,请返回它的最长无重复字符子串长度.保证A中字符全部为小写英文字符,且长度小于等于500. 测试样例: "abcdbefgdchi",12 返回:8 这个题我研究了好半天,确实不好想,看了别人的思路,半天才把代码写出来 分析: 首先定义三个辅助变量: max_len:表示字符串中最长无重复字符的子串长度,也就是函数返回值 map<char, int>:用来存放

求一字符串最长不重复字符子串的长度【Java 版】

一. 前言 最近学习有点断断续续,整理的一些知识点要么不完整,要么完全没搞懂,不好拿上台面,还是先在草稿箱躺着吧.偶尔在浏览大牛博客http://coolshell.cn的时候,发现大牛业余时间也在做编程训练http://coolshell.cn/articles/12052.html,作为一名想励志成为码农的测试猿,更应该在当下多利用业余时间,训练自己的编码能力,掌握好基础.那就开始吧,https://oj.leetcode.com/problems/ 二.正文 1.题目:Longest Su

无重复字符的最长子串

给定一个字符串,找出不含有重复字符的 最长子串 的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1. 给定 "pwwkew" ,最长子串是 "wke" ,长度是3.请注意答案必须是一个子串,"pwke" 是 子序列 而不是子串. 思路:首先其只要求返回最长