【滑窗】B018_LC_替换子串得到平衡字符串(字符计数)

一、Problem

有一个只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符,且长度为 n 的字符串。

假如在该字符串中,这四个字符都恰好出现 n/4 次,那么它就是一个「平衡字符串」。

给你一个这样的字符串 s,请通过「替换一个子串」的方式,使原字符串 s 变成一个「平衡字符串」。

你可以用和「待替换子串」长度相同的 任何 其他字符串来完成替换。

请返回待替换子串的最小可能长度。

如果原字符串自身就是一个平衡字符串,则返回 0。

输入:s = "QWER"
输出:0
解释:s 已经是平衡的了。

提示:

1 <= s.length <= 10^5
s.length 是 4 的倍数
s 中只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符

二、Solution

方法一:滑窗

  • 窗口的含义
    • 合法子串
  • 窗口右边界右移时机
    • 每次都右移
  • 窗口左边界右移时机
    • 窗口内部的字符都合法,这道题其实并不需要真的去替换字符,而是当一个子串从不合法变为合法时,一定是将某些多余的字符给隐式地替换了(mp[c]--),而给定的字符串的长度一定是 4 的倍数,所以保证可以替换成功。
  • 结算时机
    • 左移前
class Solution {
    boolean need(int[] mp, int tar) {
        return mp['Q'] <= tar && mp['W'] <= tar && mp['E'] <= tar && mp['R'] <= tar;
    }
    public int balancedString(String S) {
        int n = S.length(), tar = n >>> 2, l = 0, r = 0, ans = n+5, mp[] = new int[258];
        char[] s = S.toCharArray();
        for (char c : s) 
            mp[c]++;

        while (r < n) {
            mp[s[r]]--;
            while (l < n && need(mp, tar)) {
                mp[s[l]]++;
                ans = Math.min(ans, r-l+1);
                l++;
            }
            r++;
        }
        return ans;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n)
  • 空间复杂度: O ( 1 ) O(1)

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/106848998
今日推荐