LeetCode 1653 使字符串平衡的最少次数

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

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

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

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

示例 1:

输入:s = "aababbab"
输出:2
解释:你可以选择以下任意一种方案:
下标从 0 开始,删除第 2 和第 6 个字符("aababbab" -> "aaabbb"),
下标从 0 开始,删除第 3 和第 6 个字符("aababbab" -> "aabbbb")。
示例 2:

输入:s = "bbaaaaabb"
输出:2
解释:唯一的最优解是删除最前面两个字符。

提示:

  • 1 <= s.length <= 105
  • s[i] 要么是 'a' 要么是 'b'​

方案一:对于每一个字符,都有两种情况,删或者不删。枚举出每一种情况,取删除次数最少的。时间复杂度为 O(2n), 这种方案会超时

int helper(string &s, string &b, int i, int count) {
    if (i >= s.size()) 
        return 0x7fffffff;
    if (s == b) {
        return count;
    }
    string s1 = s;
    s1.erase(i, 1);
    string b1 = b;
    if (s[i] == 'a') {
        b1.erase(b1.begin());
    } else {
        b1.erase(b1.end() - 1);
    }
    return min(helper(s, b, i + 1, count), helper(s1, b1, i, count + 1));
}
int minimumDeletions(string s) {
    string balance = s;
    sort(balance.begin(), balance.end());
    return helper(s, balance, 0, 0);
}

方案二:假设有一条间隔,删除间隔左边的所有 'b', 删除间隔右边的所有 'a',此时的字符串是平衡的。间隔一开始在字符串的最左边,一直遍历到最右边,取修改最少的结果。

int minimumDeletions(string s) {
    int leftB = 0, rightA = 0;
    for (auto ch : s) {
        if (ch == 'a')
            ++rightA;
    }
    int res = rightA;
    for (auto ch : s) {
        if (ch == 'a') {
            --rightA;
        } else {
            ++leftB;
        }
        res = min(res, leftB + rightA);
    }
    return res;
}
posted @ 2023-03-06 14:07  卑以自牧lq  阅读(51)  评论(0)    收藏  举报