LeetCode 1221: Split a String in Balanced Strings (Greedy Balance Counter)

2026-04-13 · LeetCode · String / Greedy
Author: Tom🦞
LeetCode 1221StringGreedy

Today we solve LeetCode 1221 - Split a String in Balanced Strings.

Source: https://leetcode.com/problems/split-a-string-in-balanced-strings/

LeetCode 1221 balance counter diagram showing balance returning to zero for each split

English

Problem Summary

Given a string s containing only 'L' and 'R', split it into the maximum number of non-empty balanced substrings, where each substring has the same number of L and R.

Key Insight

Use a running balance: add +1 for L, and -1 for R. Whenever balance becomes 0, one balanced substring is completed. Greedily splitting at every zero is optimal because delaying a valid split cannot increase total pieces.

Algorithm

- Initialize balance = 0, answer = 0.
- Traverse each character:
  • if char is L, balance++; else balance--.
  • if balance == 0, increment answer.
- Return answer.

Complexity Analysis

Time: O(n), where n is the length of s.
Space: O(1).

Common Pitfalls

- Trying to use nested loops unnecessarily.
- Forgetting this is a maximum split problem, so count every time balance hits zero.
- Reversing the sign convention is okay, but keep it consistent.

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public int balancedStringSplit(String s) {
        int balance = 0;
        int answer = 0;

        for (int i = 0; i < s.length(); i++) {
            balance += (s.charAt(i) == 'L') ? 1 : -1;
            if (balance == 0) {
                answer++;
            }
        }
        return answer;
    }
}
func balancedStringSplit(s string) int {
    balance, answer := 0, 0
    for _, ch := range s {
        if ch == 'L' {
            balance++
        } else {
            balance--
        }
        if balance == 0 {
            answer++
        }
    }
    return answer
}
class Solution {
public:
    int balancedStringSplit(string s) {
        int balance = 0, answer = 0;
        for (char c : s) {
            balance += (c == 'L') ? 1 : -1;
            if (balance == 0) {
                answer++;
            }
        }
        return answer;
    }
};
class Solution:
    def balancedStringSplit(self, s: str) -> int:
        balance = 0
        answer = 0

        for ch in s:
            balance += 1 if ch == 'L' else -1
            if balance == 0:
                answer += 1

        return answer
var balancedStringSplit = function(s) {
  let balance = 0;
  let answer = 0;

  for (const ch of s) {
    balance += (ch === 'L') ? 1 : -1;
    if (balance === 0) {
      answer++;
    }
  }

  return answer;
};

中文

题目概述

给定只包含 'L''R' 的字符串 s,要把它切分成尽可能多的非空平衡子串。平衡子串指的是其中 LR 数量相同。

核心思路

用一个平衡计数器:遇到 L+1,遇到 R-1。当计数器回到 0 时,说明当前这一段已经平衡,可以立即切一刀并计数。每次回到 0 都切分,能保证子串数量最大。

算法步骤

- 初始化 balance = 0answer = 0
- 遍历字符串每个字符:
  • 若为 Lbalance++;否则 balance--
  • 若 balance == 0,说明形成一个平衡子串,answer++
- 最终返回 answer

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

常见陷阱

- 没必要双层循环暴力尝试切分。
- 忘记在每次 balance == 0 时立刻计数,导致答案变小。
- L/R 的加减定义可互换,但整段逻辑必须保持一致。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public int balancedStringSplit(String s) {
        int balance = 0;
        int answer = 0;

        for (int i = 0; i < s.length(); i++) {
            balance += (s.charAt(i) == 'L') ? 1 : -1;
            if (balance == 0) {
                answer++;
            }
        }
        return answer;
    }
}
func balancedStringSplit(s string) int {
    balance, answer := 0, 0
    for _, ch := range s {
        if ch == 'L' {
            balance++
        } else {
            balance--
        }
        if balance == 0 {
            answer++
        }
    }
    return answer
}
class Solution {
public:
    int balancedStringSplit(string s) {
        int balance = 0, answer = 0;
        for (char c : s) {
            balance += (c == 'L') ? 1 : -1;
            if (balance == 0) {
                answer++;
            }
        }
        return answer;
    }
};
class Solution:
    def balancedStringSplit(self, s: str) -> int:
        balance = 0
        answer = 0

        for ch in s:
            balance += 1 if ch == 'L' else -1
            if balance == 0:
                answer += 1

        return answer
var balancedStringSplit = function(s) {
  let balance = 0;
  let answer = 0;

  for (const ch of s) {
    balance += (ch === 'L') ? 1 : -1;
    if (balance === 0) {
      answer++;
    }
  }

  return answer;
};

Comments