题目: 1221.分割平衡字符串

题面

平衡字符串 中,‘L’ 和 ‘R’ 字符的数量是相同的。

给你一个平衡字符串 s,请你将它分割成尽可能多的子字符串,并满足:

每个子字符串都是平衡字符串。
返回可以通过分割得到的平衡字符串的 最大数量 。

示例

示例 1:

输入:s = “RLRRLLRLRL”
输出:4
解释:s 可以分割为 “RL”、“RRLL”、“RL”、“RL” ,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
示例 2:

输入:s = “RLRRRLLRLL”
输出:2
解释:s 可以分割为 “RL”、“RRRLLRLL”,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
注意,s 无法分割为 “RL”、“RR”、“RL”、“LR”、“LL” 因为第 2 个和第 5 个子字符串不是平衡字符串。
示例 3:

输入:s = “LLLLRRRR”
输出:1
解释:s 只能保持原样 “LLLLRRRR” 。

Tips

2 <= s.length <= 1000
s[i] = ‘L’ 或 ‘R’
s 是一个 平衡 字符串

Code

代码展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int balancedStringSplit(string s) {
int cnt = 0, ans = 0; // 初始化两个整数变量 cnt 和 ans。cnt 用来追踪当前平衡状态,ans 用来记录平衡子字符串的数量。

for (char c: s) { // 使用范围循环(range-based loop),遍历字符串 s 中的每一个字符 c。
cnt += c == 'L' ? 1 : -1; // 如果当前字符 c 是 'L',则 cnt 增加 1;否则(即 c 是 'R'),cnt 减少 1。

if (cnt == 0) ans++; // 当 cnt 变为 0 时,表示从上一个平衡点到当前字符之间的部分是一个平衡子字符串,因此 ans 增加 1。
}

return ans; // 返回 ans 的值,即找到的最大平衡子字符串的数量。
}
};

逐行解释

  1. class Solution { ... };:

    • 定义一个名为 Solution 的类。在 LeetCode 上的代码通常需要将函数封装在一个类中,这个类的名字通常为 Solution
  2. int balancedStringSplit(string s):

    • Solution 类中定义了一个返回整数的函数 balancedStringSplit,该函数接受一个字符串 s 作为输入。这个函数的目的是计算并返回字符串 s 中可以分割成的最大平衡子字符串数量。
  3. int cnt = 0, ans = 0;:

    • 定义并初始化两个整数变量 cntans 为 0。
    • cnt 用于跟踪当前的平衡状态:遇到 ‘L’ 字符时,cnt 增加 1;遇到 ‘R’ 字符时,cnt 减少 1。当 cnt 为 0 时,表示当前子字符串是平衡的。
    • ans 用于记录找到的平衡子字符串的数量。
  4. for (char c: s) { ... }:

    • 使用范围循环遍历字符串 s 中的每个字符 c
  5. cnt += c == 'L' ? 1 : -1;:

    • 这是一行紧凑的代码,使用了三元运算符 ? :
    • 具体来说,这行代码的意思是:如果字符 c 是 ‘L’,那么 cnt 增加 1;否则(字符 c 是 ‘R’),cnt 减少 1。
  6. if (cnt == 0) ans++;:

    • 检查当前 cnt 是否为 0。如果 cnt 为 0,表示从上一个平衡点到当前字符构成了一个平衡子字符串,所以将 ans 增加 1。
  7. return ans;:

    • 最后,返回 ans 的值,即可以得到的最大平衡子字符串的数量。

逻辑总结

  • 通过遍历字符串 s,我们跟踪当前的平衡状态。
  • 每当计数器 cnt 为 0 时,表示找到了一个完整的平衡子字符串,因此我们增加计数器 ans
  • 最终,ans 的值就是可以通过分割字符串 s 得到的最大平衡子字符串的数量。

这个算法的时间复杂度为 O(n),其中 n 是字符串的长度,因此对于大规模输入也能高效处理。