• 【leetcode】1234. Replace the Substring for Balanced String


    题目如下:

    You are given a string containing only 4 kinds of characters 'Q', 'W', 'E' and 'R'.

    A string is said to be balanced if each of its characters appears n/4 times where n is the length of the string.

    Return the minimum length of the substring that can be replaced with any other string of the same length to make the original string s balanced.

    Return 0 if the string is already balanced. 

    Example 1:

    Input: s = "QWER"
    Output: 0
    Explanation: s is already balanced.

    Example 2:

    Input: s = "QQWE"
    Output: 1
    Explanation: We need to replace a 'Q' to 'R', so that "RQWE" (or "QRWE") is balanced.
    

    Example 3:

    Input: s = "QQQW"
    Output: 2
    Explanation: We can replace the first "QQ" to "ER". 
    

    Example 4:

    Input: s = "QQQQ"
    Output: 3
    Explanation: We can replace the last 3 'Q' to make s = "QWER".

    Constraints:

    • 1 <= s.length <= 10^5
    • s.length is a multiple of 4
    • contains only 'Q''W''E' and 'R'.

    解题思路:如果字符串需要替换后才能到达平衡,那么说明至少有一个字符出现的次数超过1/4,当然至多也只有三个字符出现的次数都超过1/4。假设x1...xn为超过1/4的字符,那么就需要将xn们替换成不超过1/4的字符,具体每个xn需要替换的次数为 xn出现的次数 - len(s)/4,记为dn。所以题目就转换成找出一个最短的字符串,使得至少要包含dn的xn。如下图,输入为:WQWRQQQW,很容易可以求出每个字符在[0~i]区间内出现的个数,假设符合题目要求的子字符串是从下标i开始,只需要找出Q[i] + dn出现的下标j,即表示在i~j区间内Q出现的个数满足最小需要删除的个数,因为Q在区间内出现的次数有序,这里可以用二分查找,同时求出其他超过1/4的字符对应出现的下标,并求出这些下标的最大值,这个最大值就是子字符串是从下标i开始满足题目要求的子字符串最小的长度,遍历整个输入,求出[0~len(s)]区间内最小的长度即可。

     代码如下:

    class Solution(object):
        def balancedString(self, s):
            """
            :type s: str
            :rtype: int
            """
            dic = {'Q':{},'W':{},'E':{},'R':{}}
            char = ['Q','W','E','R']
            char_count = [0,0,0,0]
            s = s.replace('
    ','')
            for i in range(len(s)):
                inx = char.index(s[i])
                char_count[inx] += 1
                dic[s[i]][char_count[inx]] = i
    
            res = float('inf')
            char_count_2 = [0, 0, 0, 0]
            for i in range(len(s)):
                inx = char.index(s[i])
                if char_count[inx] <= len(s)/4:
                    continue
                count = -float('inf')
                for j in range(len(char)):
                    if char_count[j] <= len(s)/4:
                        continue
                    diff = char_count[j] - len(s)/4
                    if char_count_2[j] + diff in dic[char[j]]:
                        end = dic[char[j]][char_count_2[j] + diff]
                        count = max(count, end - i +1)
                    else:
                        count = -float('inf')
                        break
                if count != -float('inf'):
                    res = min(res,count)
                char_count_2[inx] += 1
            return res if res != float('inf') else 0
  • 相关阅读:
    用户需求调研报告
    返回一个二维数组中的最大联通子数组(补)
    代码大全读后感(3)
    代码大全读后感(2)
    返回一个二维整数数组中最大联通子数组的和
    冲刺第一阶段总结
    大道至简读书笔记三
    大道至简读书笔记二
    大道至简读书笔记一
    软件工程课程改进意见
  • 原文地址:https://www.cnblogs.com/seyjs/p/11730704.html
Copyright © 2020-2023  润新知