使所有字符相等的最小成本
- 题目
- 示例
- 示例1
- 示例2
- 题解
- 这些话乍一看可能看不懂,但是多读两遍就明白了。
- 很神奇的解法,像魔术一样。
题目
给你一个下标从 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
。至此其实已经结束了,我们只要汇总i
和n-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)