[HOT 100] 1234. 替换子串得到平衡字符串

文章目录

      • 1. 题目链接
      • 2. 题目描述
      • 3. 题目示例
      • 4. 解题思路
      • 5. 题解代码
      • 6. 复杂度分析

1. 题目链接


1234. 替换子串得到平衡字符串 - 力扣(LeetCode)


2. 题目描述


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

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

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

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

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

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


3. 题目示例


示例 1 :

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

示例 2 :

输入:s = "QQWE"
输出:1
解释:我们需要把一个 'Q' 替换成 'R',这样得到的 "RQWE" (或 "QRWE") 是平衡的。

示例 3 :

输入:s = "QQQW"
输出:2
解释:我们可以把前面的 "QQ" 替换成 "ER"。

示例 4 :

输入:s = "QQQQ"
输出:3
解释:我们可以替换后 3 个 'Q',使 s = "QWER"。

4. 解题思路


  • 字符计数: 首先统计字符串中每个字符 'Q''W''E''R' 的出现次数。我们将目标设定为每个字符在字符串中的出现次数应该是 n / 4,其中 n 是字符串的长度。
  • 如果已经满足条件: 如果字符串中的每个字符已经平衡(即每个字符的出现次数等于 n / 4),则直接返回 0,表示不需要任何操作。
  • 滑动窗口: 如果某些字符的出现次数超过了 n / 4,我们可以通过滑动窗口来找到最小的子串,使得通过替换这个子串中的字符,可以将字符串变为平衡字符串。具体步骤是:
  • 使用两个指针 leftright 表示当前滑动窗口的左右边界。
  • 逐步扩展右指针,更新窗口内各个字符的计数。
  • 如果当前窗口内的字符满足平衡条件(即每个字符的出现次数都不超过 n / 4),更新答案为当前窗口的大小。
  • 最小替换次数: 最终的结果是滑动窗口中符合条件的最小子串的长度,即为最小的替换次数。

5. 题解代码


class Solution {
    public int balancedString(String S) {
        char[] s = S.toCharArray();  // 将字符串转为字符数组
        int[] cnt = new int['X'];  // 统计字符的出现次数
        for (char c : s)  // 遍历字符串,统计每个字符的次数
            cnt[c]++;
        
        int n = s.length;  // 字符串长度
        int m = n / 4;  // 每个字符应该出现的次数
        
        // 如果每个字符已经满足平衡,直接返回 0
        if (cnt['Q'] == m && cnt['W'] == m && cnt['E'] == m && cnt['R'] == m)
            return 0;
        
        int ans = n;  // 初始化答案为字符串长度
        int left = 0;
        
        // 扩展右指针
        for (int right = 0; right < n; right++) {
            cnt[s[right]]--;  // 更新窗口内的字符计数
            
            // 当窗口内每个字符都满足平衡条件时,收缩窗口
            while (cnt['Q'] <= m && cnt['W'] <= m && cnt['E'] <= m && cnt['R'] <= m) {
                ans = Math.min(ans, right - left + 1);  // 更新最小窗口长度
                cnt[s[left++]]++;  // 移动左指针,收缩窗口
            }
        }
        return ans;  // 返回最小替换次数
    }
}


6. 复杂度分析


  • 时间复杂度O(n),其中 n 是字符串的长度。右指针遍历整个数组,每个元素最多被左指针和右指针访问一次,因此时间复杂度为线性时间。
  • 空间复杂度O(1),因为字符计数数组的大小是固定的(大小为 90),空间复杂度是常数级别。

你可能感兴趣的:(算法,HOT,100)