leetcode-master/problems/1221.分割平衡字符串.md

164 lines
4.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p align="center">
<a href="https://programmercarl.com/other/xunlianying.html" target="_blank">
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 1221. 分割平衡字符串
[力扣题目链接](https://leetcode.cn/problems/split-a-string-in-balanced-strings/)
在一个 平衡字符串 中,'L' 和 'R' 字符的数量是相同的。
给你一个平衡字符串 s请你将它分割成尽可能多的平衡字符串。
注意:分割得到的每个字符串都必须是平衡字符串。
返回可以通过分割得到的平衡字符串的 最大数量 。
示例 1
* 输入s = "RLRRLLRLRL"
* 输出4
* 解释s 可以分割为 "RL"、"RRLL"、"RL"、"RL" ,每个子字符串中都包含相同数量的 'L' 和 'R' 。
示例 2
* 输入s = "RLLLLRRRLR"
* 输出3
* 解释s 可以分割为 "RL"、"LLLRRR"、"LR" ,每个子字符串中都包含相同数量的 'L' 和 'R' 。
示例 3
* 输入s = "LLLLRRRR"
* 输出1
* 解释s 只能保持原样 "LLLLRRRR".
示例 4
* 输入s = "RLRRRLLRLL"
* 输出2
* 解释s 可以分割为 "RL"、"RRRLLRLL" ,每个子字符串中都包含相同数量的 'L' 和 'R' 。
## 思路
这道题目看起来好像很复杂,其实是非常简单的贪心,关于贪心,我在这里[关于贪心算法,你该了解这些!](https://programmercarl.com/贪心算法理论基础.html)有详细的讲解。
从前向后遍历,只要遇到平衡子串,计数就+1遍历一遍即可。
局部最优:从前向后遍历,只要遇到平衡子串 就统计
全局最优:统计了最多的平衡子串。
局部最优可以推出全局最优,举不出反例,那么就试试贪心。
例如LRLR 这本身就是平衡子串 , 但要遇到LR就可以分割。
C++代码如下:
```CPP
class Solution {
public:
int balancedStringSplit(string s) {
int result = 0;
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'R') count++;
else count--;
if (count == 0) result++;
}
return result;
}
};
```
## 拓展
一些同学可能想,你这个推理不靠谱,都没有数学证明。怎么就能说是合理的呢,怎么就能说明 局部最优可以推出全局最优呢?
一般数学证明有如下两种方法:
* 数学归纳法
* 反证法
如果真的去严格数学证明其实不是在我们刷题或者 面试的考察范围内了。
所以贪心题目的思考过程是: 如果发现局部最优好像可以推出全局最优,那么就 尝试一下举反例,如果举不出反例,那么就试试贪心。
## 其他语言版本
### Java
```java
class Solution {
public int balancedStringSplit(String s) {
int result = 0;
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == 'R') count++;
else count--;
if (count == 0) result++;
}
return result;
}
}
```
### Python
```python
class Solution:
def balancedStringSplit(self, s: str) -> int:
diff = 0 #右左差值
ans = 0
for c in s:
if c == "L":
diff -= 1
else:
diff += 1
if diff == 0:
ans += 1
return ans
```
### Go
```go
func balancedStringSplit(s string) int {
diff := 0 // 右左差值
ans := 0
for _, c := range s {
if c == 'L' {
diff--
}else {
diff++
}
if diff == 0 {
ans++
}
}
return ans
}
```
### JavaScript
```js
var balancedStringSplit = function(s) {
let res = 0, total = 0;//res为平衡字符串数量 total为当前"R"字符和"L"字符的数量差
for(let c of s){// 遍历字符串每个字符
//因为开始字符数量差就是0遍历的时候要先改变数量差否则会影响结果数量
total += c === 'R' ? 1:-1;//遇到"R",total++;遇到"L",total--
if(total === 0) res++;//只要"R""L"数量一样就可以算是一个平衡字符串
}
return res;
};
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>