当前位置:首页 > 牛客 > 牛客14778题解析:滑动窗口算法破解字符替换问题的最优解

牛客14778题解析:滑动窗口算法破解字符替换问题的最优解

1天前

牛客14778题解析:滑动窗口算法破解字符替换问题的最优解 牛客14778题解析 滑动窗口算法 字符替换问题 最长连续子串 动态规划优化 第1张

一、题目解读

牛客14778题要求给定字符串s、替换次数上限m及目标字符,求解在s中通过最多m次替换操作,得到的最长连续子串长度。例如,当s="abcbab",m=2,target='a'时,需将'b'替换为'a',最终得到"abcaab",子串长度为5。题目核心在于平衡替换次数与子串长度,需高效算法解决。

二、解题思路

采用滑动窗口 + 双指针策略。通过维护左右指针动态调整窗口大小,实时统计替换次数:

1. 右指针右移时,若遇到非目标字符则增加替换次数;

2. 当替换次数超m时,左指针右移缩减窗口,同时减少替换计数;

3. 实时更新窗口内最长长度。

该思路巧妙将替换次数与子串范围关联,避免暴力枚举时间复杂度降为O(n)。

三、解题步骤详解

1. 初始化变量:left=0(左指针),max_len=0(最长长度),cost=0(当前替换次数)。

2. 右指针遍历:每移动一次,若当前字符≠target,则cost++。

3. 动态调整窗口:当cost>m时,左指针右移并递减cost(若移出字符非target)。

4. 更新结果:每次窗口调整完成后,计算right-left+1与max_len的较大值。

5. 双目标求解:主函数中分别调用solve()计算全a和全b的最长长度,取两者最大值输出。

四、代码与注释

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

// 求解指定target下的最长子串长度
int solve(const string &s, int m, char target) {
    int left = 0, max_len = 0, cost = 0; // 窗口左边界、最长长度、替换次数
    for (int right = 0; right < s.size(); ++right) { // 右指针遍历
        if (s[right]!= target) cost++; // 非目标字符则替换次数+1
        while (cost > m) { // 若替换超限
            if (s[left]!= target) cost--; // 左移窗口,若移出字符需替换则减次数
            left++;
        }
        max_len = max(max_len, right - left + 1); // 更新最长长度
    }
    return max_len;
}

int main() {
    ios::sync_with_stdio(false); // 加速输入输出
    cin.tie(nullptr);
    
    int n, m; // 可忽略,n无用
    string s;
    cin >> n >> m >> s; // 输入m和s
    
    int max_a = solve(s, m, 'a'); // 计算全a情况
    int max_b = solve(s, m, 'b'); // 计算全b情况
    cout << max(max_a, max_b) << endl; // 输出两者最大值
    return 0;
}

五、总结

本文代码通过滑动窗口算法,将字符替换与动态区间维护结合,高效解决牛客14778题。该解法关键点:

1. 利用双指针动态平衡替换次数与子串长度;

2. 避免冗余计算,实现线性时间复杂度;

3. 适用于同类替换限制下的最值求解场景。

掌握此思路可拓展至更多动态规划优化问题。

原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。