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

文章描述了一道编程题,目标是将包含a和b的字符串转化为左边全a,右边全b,并求最少删除次数。作者分享了从无头绪到找到解决方案的过程,首先尝试双重循环方法但导致超时,然后优化为只操作a,通过遍历计算最小删除次数。
摘要由CSDN通过智能技术生成

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

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

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

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

这道题简单来说 就是将字符串转换成左边全是a,右边全是b,最少需要多少步。

拿到手之后,没有多少思路,即使理解了题目是要求,但是却想不到怎么去解决这个问题。

查看了一些资料之后,得到一个思路,以一个字符为基准,将基准左侧的b去掉,基准右侧的a去掉,这样就得到了想要的结果。

于是立刻开始双重循环,伪代码如下:

int min = Max
for(i...) {
    int count = 0;
    for(j = 0; j < i) {
        // 获取左侧b的数量
        count++
    }

    for(j= i + 1;j < length) {
        // 获取右侧a的数量
        count++
    }
    min = Math.min(min, count)
}

结果运行之后,超时了,可以看出这道题不仅思路比较难想,对复杂度也有要求。

只能再找资料优化,得到新的思路,与其既操作a和b,不如就只操作a,最大步数就是把a全部删除的步数,这时候再一次遍历,如果当前字符是a,则步数减一(因为在基准的左侧是不允许有b的,所以当前字符是a时,当前的a是不需要删除的,而最大步数里肯定是加了当前的a的,所以需要把最大步数减一),如果当前字符是b,则需要删除当前的b字符(因为每找到一个b,在下一步操作时,为了保证左侧没有b,需要将b删掉,这样就要多走一部,所以最大步数要加一)

以该字符串为例 : "aababbab"

第一次循环,max = 4;

第二次循环  (以下括号内为需要操作删除的字符)

i = 0,   max =  4 - 1 =3   得到结果是 a(a)b(a)bb(a)b

i = 1,     max =  3 -1  = 2   得到结果是 aab(a)bb(a)b

i = 2,    max  = 2 +1 = 3   得到结果是 aa(b)(a)bb(a)b

i = 3,    max = 3 - 1 = 2   得到结果是  aa(b)abb(a)b

i = 4,    max = 2 + 1 = 3  得到结果是  aa(b)a(b)b(a)b

i = 5,    max = 3 + 1 = 4  得到结果是  aa(b)a(b)(b)(a)b

i = 6,   max = 4 - 1 = 3    得到结果是  aa(b)a(b)(b)ab

i = 7,   max = 3 + 1 = 4    得到结果是  aa(b)a(b)(b)a(b)

得出最小值是2

代码如下:

public int minimumDeletions2(String s) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == 'a') {
                count ++;
            }
        }

        int res = count;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == 'a') {
                count --;
            } else {
                count ++;
            }
            if (res > count) {
                res = count;
            }
        }
        return res;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值