C语言/数据结构滑动窗口题解:替换k个字符后的最长连续相同字符子串(LeetCode 424)

问题描述

小红在玩一个字符串游戏,她有一个由大写字母组成的字符串 s 和一个整数 k。游戏规则允许她进行最多 k 次字符替换操作(每次操作可以将任意一个字符替换成另一个大写字母),她希望通过这些操作使得字符串中出现一个尽可能长的由相同字符组成的连续子串。

例如,如果字符串是 "AABBBCC",k = 2,小红可以将两个 'C' 替换成 'B',从而得到全为 'B' 的子串 "BBBBBB",长度为 7。

请你帮助小红设计一个算法,计算在最多进行 k 次替换后,字符串中最长的连续相同字符子串的长度。

测试样例

样例1:

输入:s = "ABAB", k = 2 输出:4 解释:将两个 'A' 替换为 'B',或者将两个 'B' 替换为 'A',可以得到全为 'A' 或全为 'B' 的字符串,最长子串长度为 4。

样例2:

输入:s = "AABABBA", k = 1 输出:4 解释:将中间的一个 'A' 替换为 'B',可以得到 "AABBBBA",其中 "BBBB" 是长度为 4 的连续相同字符子串。

样例3:

输入:s = "ABCDE", k = 2 输出:3 解释:例如,将 'C' 和 'D' 替换为 'B',可以得到 "ABBBE",其中 "BBB" 是长度为 3 的连续子串。

约束条件

  • 1 ≤ s.length ≤ 10^5
  • s 仅由大写英文字母组成
  • 0 ≤ k ≤ s.length
  • 要求算法时间复杂度为 O(n) 或 O(n log n)

程序代码

#include <stdio.h>

#include <string.h>

int characterReplacement(char* s, int k) {

int count26 = {0}; // 记录窗口内每个字符的出现次数

int left = 0;

int maxCount = 0; // 窗口内出现次数最多的字符的次数

int maxLen = 0;

int len = strlen(s);

for (int right = 0; right < len; right++) {

int idx = sright - 'A';

countidx++;

if (countidx > maxCount) {

maxCount = countidx;

}

// 当前窗口长度 = right - left + 1

// 需要替换的字符数 = 窗口长度 - maxCount

// 如果超过 k,说明这个窗口无法通过 k 次替换变成全相同字符

while ((right - left + 1) - maxCount > k) {

counts\[left - 'A']--;

left++;

}

// 更新最大长度

int curLen = right - left + 1;

if (curLen > maxLen) {

maxLen = curLen;

}

}

return maxLen;

}

int main() {

printf("%d\n", characterReplacement("ABAB", 2)); // 应输出 4

printf("%d\n", characterReplacement("AABABBA", 1)); // 应输出 4

printf("%d\n", characterReplacement("ABCDE", 2)); // 应输出 3

return 0;

}

cpp 复制代码
#include <stdio.h>
#include <string.h>

int characterReplacement(char* s, int k) {
    int count[26] = {0};  // 记录窗口内每个字符的出现次数
    int left = 0;
    int maxCount = 0;     // 窗口内出现次数最多的字符的次数
    int maxLen = 0;
    int len = strlen(s);

    for (int right = 0; right < len; right++) {
        int idx = s[right] - 'A';
        count[idx]++;
        if (count[idx] > maxCount) {
            maxCount = count[idx];
        }

        // 当前窗口长度 = right - left + 1
        // 需要替换的字符数 = 窗口长度 - maxCount
        // 如果超过 k,说明这个窗口无法通过 k 次替换变成全相同字符
        while ((right - left + 1) - maxCount > k) {
            count[s[left] - 'A']--;
            left++;
        }

        // 更新最大长度
        int curLen = right - left + 1;
        if (curLen > maxLen) {
            maxLen = curLen;
        }
    }

    return maxLen;
}

int main() {
    printf("%d\n", characterReplacement("ABAB", 2));      // 应输出 4
    printf("%d\n", characterReplacement("AABABBA", 1));   // 应输出 4
    printf("%d\n", characterReplacement("ABCDE", 2));     // 应输出 3
    return 0;
}

运行结果

相关推荐
启观川2 分钟前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
wuminyu1 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
Logic1012 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
yi0112 小时前
LeetCode 643. 子数组最大平均数 I|从暴力枚举到滑动窗口
人工智能·笔记·python·算法·leetcode·滑动窗口
flinn_small4 小时前
三分算法:原理、实现与实战应用
数据结构·算法·三分
老王爱玩车4 小时前
文件操作从打开到缓冲区
c语言·开发语言·学习
INGNIGHT4 小时前
944 · 最大子矩阵(前缀和)
数据结构·c++·算法
All for pursuit.5 小时前
【动态规划-6】96.不同的二叉搜索树
数据结构·c++·算法·leetcode·动态规划
Zwawa5 小时前
传感器模块都在交出什么:从模拟电压到数字协议
c语言·单片机·嵌入式
信奥卷王6 小时前
[GESP202609 六级] 数组划分
数据结构·算法