Ansible之Playbook

如何重置Mariadb的root密码

  返回  

【Leetcode】1234. Replace the Substring for Balanced String

2021/7/21 13:16:08 浏览:

题目地址:

https://leetcode.com/problems/replace-the-substring-for-balanced-string/

给定一个只含字母'Q', 'W', 'E', 'R'的长 n n n字符串 s s s,保证 4 ∣ n 4|n 4n。现在要求选取一段子串,可以将这个子串改为任意等长的子串,使得 s s s中四个字母都出现 n / 4 n/4 n/4次(此时称 s s s平衡)。问选取的子串最短的长度是多少。答案可以是 0 0 0

思路是双指针。先求一下 s s s里四个字母各自出现了多少次,记 c [ x ] c[x] c[x]是字母 x x x出现次数,如果刚好每个字母都出现不超过 n / 4 n/4 n/4次,那说明不需要修改,直接返回 0 0 0。接着开始用双指针算法,开快慢两指针 i i i j j j,直接用 c c c来维护区间 [ i , j ] [i,j] [i,j]之外的每个字母出现次数。每轮循环,我们尝试求以 s [ i ] s[i] s[i]为右端点的,符合条件的最短区间的长度。如果每个字母在 c c c里的计数都小于等于 n / 4 n/4 n/4,则说明可以适当修改当前维护区间 [ i , j ] [i,j] [i,j]使得 n n n平衡,更新答案,并尝试右移左端点 j j j,直到不满足条件为止,则继续枚举右端点,即使 i i i右移。注意此时不用回退 j j j,因为题目要求最短的符合条件的区间,回退 j j j只会使得区间更长,并不会得到更优解。代码如下:

public class Solution {
    public int balancedString(String s) {
        int[] tot = new int[256];
        for (int i = 0; i < s.length(); i++) {
            tot[s.charAt(i)]++;
        }
        
        char[] chs = {'Q', 'W', 'E', 'R'};
        // 这里check的原因是,答案有可能是空串,但是下面的双指针算法没有枚举空区间的情况
        if (check(tot, s.length() / 4, chs)) {
            return 0;
        }
        
        int res = s.length();
        for (int i = 0, j = 0; i < s.length(); i++) {
            tot[s.charAt(i)]--;
            while (j <= i && check(tot, s.length() / 4, chs)) {
            	// 符合条件,更新答案,并右移左端点
                res = Math.min(res, i - j + 1);
                tot[s.charAt(j)]++;
                j++;
            }
        }
        
        return res;
    }
    
    private boolean check(int[] tot, int k, char[] chs) {
        for (char ch : chs) {
            if (tot[ch] > k) {
                return false;
            }
        }
        
        return true;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号