1653. 使字符串平衡的最少删除次数

218 阅读1分钟

题目:
给你一个字符串 s ,它仅包含字符 'a' 和 'b'​​​​ 。

你可以删除 s 中任意数目的字符,使得 s 平衡 。我们称 s 平衡的 当不存在下标对 (i,j) 满足 i < j 且 s[i] = 'b' 同时 s[j]= 'a' 。

请你返回使 s 平衡 的 最少 删除次数。

算法:
方法一:前缀和
这他喵的,这种计算模型又笨又很合理。

遍历字符串,统计对每个位置i,i之前(包括i)的b的个数bCount,i之后的a的个数aCount, 求bCoubt + aCount的最小值

func minimumDeletions(s string) int {
    count := make([]int, len(s) + 1)
    for i := range s {
        if s[i] == 'a' {
            count[i + 1] = count[i] + 1 
        } else {
            count[i + 1] = count[i]
        }
    }
    n := len(s)
    ans := math.MaxInt32
    for i := 0; i < len(s); i ++ {
        // s分割成两个子串[0 ~ i][i + 1, n - 1]
        // 计算左子串包含的的b的个数bCount,和右子串包含的a的个数aCount
        bCount := i - count[i]
        aCount := count[n] - count[i + 1]
        
        ans = min(ans, aCount + bCount)
    }
    return ans
}
func min(a, b int) int {
    if a < b {
        return a 
    }
    return b
}

方法二:动态规划
dp[i]表示i位置删除最少次数是字符串平衡。
如果s[i] = b, 那么dp[i] = dp[i - 1]
如果s[i] = a, 那么我们可以删光i之前的所有b,或者删除a dp[i] = min(bCount, dp[i - 1] + 1)

func minimumDeletions(s string) int {
    pre, cur := 0, 0
    bCount := 0
    for i := range s {
        if s[i] == 'a' {
            cur = min(bCount, pre + 1)
        } else {
            bCount ++
            cur = pre
        }
        pre = cur
    }
    return cur
}
func min(a, b int) int {
    if a < b {
        return a 
    }
    return b
}