力扣每日一题:2712——使所有字符相等的最小成本

题目

给你一个下标从 0 开始、长度为 n 的二进制字符串 s ,你可以对其执行两种操作:

选中一个下标 i 并且反转从下标0到下标 i(包括下标0和下标i)的所有字符,成本为i + 1
选中一个下标 i 并且反转从下标i到下标 n - 1(包括下标i和下标n - 1)的所有字符,成本为 n - i
返回使字符串内所有字符 相等 需要的 最小成本 。

反转 字符意味着:如果原来的值是 ‘0’ ,则反转后值变为 ‘1’ ,反之亦然。

示例

示例1

输入:s = “0011”
输出:2
解释:执行第二种操作,选中下标 i = 2 ,可以得到 s = “0000” ,成本为 2 。可以证明 2 是使所有字符相等的最小成本。

示例2

输入:s = “010101”
输出:9
解释:执行第一种操作,选中下标 i = 2 ,可以得到 s = “101101” ,成本为 3 。
执行第一种操作,选中下标 i = 1 ,可以得到 s = “011101” ,成本为 2 。
执行第一种操作,选中下标 i = 0 ,可以得到 s = “111101” ,成本为 1 。
执行第二种操作,选中下标 i = 4 ,可以得到 s = “111110” ,成本为 2 。
执行第二种操作,选中下标 i = 5 ,可以得到 s = “111111” ,成本为 1 。
使所有字符相等的总成本等于 9 。可以证明 9 是使所有字符相等的最小成本。

题解

看起来这道题目又是一个很复杂的东西,但是我看到了一个天才一般的题解。他的思路很新奇:

如果 s[i−1]≠s[i],那么必须反转,不然这两个字符无法相等。

要么反转前缀s[0] s[i−1],成本为 i
要么反转后缀s[i] s[n−1],成本为 n−i

反转后 s[i−1]=s[i]
注意到,反转操作只会改变 s[i−1] 与 s[i] 是否相等,不会改变其他相邻字符是否相等(相等的都反转还是相等,不相等的都反转还是不相等),所以每对相邻字符其实是互相独立的,我们只需要分别计算这些不相等的相邻字符的最小成本,即 min(i,n−i),累加即为答案。

这些话乍一看可能看不懂,但是多读两遍就明白了。

  • 我们让两个不同的二进制相同,只能翻转。只有翻转其中一个才能让两个相等,才能让整个字符串朝着全部相同内容更进一步。
  • 知道了上面这一点,我们就可以开始工作了:两个字符不相等,需要翻转。但是我们需要最小成本的翻转,所以要考虑到最小成本,那么如何让两个字符最小翻转呢,也就是上面提到的两种方式:一种成本为i,一种成本为n-i。至此其实已经结束了,我们只要汇总in-i谁更小就行了。

举个例子补充说明一下:
拿第一个示例来玩:

  • 字符串:0011
  • 第0个和第1个相等,不管了
  • 第1个和第2个不相等,要管,需要翻转。第一种方案成本2,第二种成本2。所以成本为2
  • 第2个和第3个相等,不管了
  • over,成本总共为2

第二个示例:

  • 字符串:010101
  • 第0个和第1个不相等,要管,需要翻转。第一种方案成本1,第二种方案成本5。所以成本为1
  • 第1个和第2个不相等,要管,需要翻转。第一种方案成本2,第二种方案成本4。所以成本为2
  • 第2个和第3个不相等,要管,需要翻转。第一种方案成本3,第二种方案成本3。所以成本为3
  • 第3个和第4个不相等,要管,需要翻转。第一种方案成本4,第二种方案成本2。所以成本为2
  • 第4个和第5个不相等,要管,需要翻转。第一种方案成本5,第二种方案成本1。所以成本为1
  • over,成本总共为1+2+3+2+1=9

很神奇的解法,像魔术一样。

class Solution {
    public long minimumCost(String s) {
        long n = s.length();
        long ans = 0;
        for(int i = 1;i<n;i++){
            if(s.charAt(i-1) != s.charAt(i)){
                ans += Math.min(i,n-i);
            }
        }
        return ans;
    }
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-cost-to-make-all-characters-equal/solutions/2286922/yi-ci-bian-li-jian-ji-xie-fa-pythonjavac-aut0/
来源:力扣(LeetCode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优降宁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值