Program to find number of good ways to split a string using Python

Suppose we have a string s. A split is said to be a good split when we can split s into 2 non-empty strings p and q where their concatenation equals s and the number of distinct letters in p and q are equal. We need to find the number of good splits we can make in s.

For example, if the input is s = "xxzxyx", then the output will be 2. We can split it as ("xxz", "xyx") or ("xxzx", "yx") ? both are good splits since each part has the same number of distinct characters.

Algorithm

To solve this problem, we will follow these steps ?

  • Initialize result = 0

  • Create left as an empty counter for the left part

  • Create right counter with frequency of each character in s

  • For each character c in s:

    • Add c to left counter: left[c] += 1

    • Remove c from right counter: right[c] -= 1

    • If right[c] becomes zero, delete it from right counter

    • If size of left equals size of right, increment result

  • Return result

Implementation

from collections import Counter

def solve(s):
    result = 0
    left, right = Counter(), Counter(s)
    
    for c in s:
        left[c] += 1
        right[c] -= 1
        
        if not right[c]:
            del right[c]
            
        if len(left) == len(right):
            result += 1
    
    return result

# Test the function
s = "xxzxyx"
print(f"String: {s}")
print(f"Number of good splits: {solve(s)}")
String: xxzxyx
Number of good splits: 2

How It Works

Let's trace through the example "xxzxyx" step by step ?

from collections import Counter

def solve_with_trace(s):
    result = 0
    left, right = Counter(), Counter(s)
    
    print(f"Initial right counter: {dict(right)}")
    print()
    
    for i, c in enumerate(s):
        left[c] += 1
        right[c] -= 1
        
        if not right[c]:
            del right[c]
        
        print(f"After processing '{c}' at position {i}:")
        print(f"  Left part: '{s[:i+1]}' ? distinct chars: {len(left)}")
        print(f"  Right part: '{s[i+1:]}' ? distinct chars: {len(right)}")
        
        if len(left) == len(right):
            result += 1
            print(f"  ? Good split found! Total: {result}")
        print()
    
    return result

s = "xxzxyx"
solve_with_trace(s)
Initial right counter: {'x': 3, 'z': 1, 'y': 1}

After processing 'x' at position 0:
  Left part: 'x' ? distinct chars: 1
  Right part: 'xzxyx' ? distinct chars: 3

After processing 'x' at position 1:
  Left part: 'xx' ? distinct chars: 1
  Right part: 'zxyx' ? distinct chars: 3

After processing 'z' at position 2:
  Left part: 'xxz' ? distinct chars: 2
  Right part: 'xyx' ? distinct chars: 2
  ? Good split found! Total: 1

After processing 'x' at position 3:
  Left part: 'xxzx' ? distinct chars: 2
  Right part: 'yx' ? distinct chars: 2
  ? Good split found! Total: 2

After processing 'y' at position 4:
  Left part: 'xxzxy' ? distinct chars: 3
  Right part: 'x' ? distinct chars: 1

After processing 'x' at position 5:
  Left part: 'xxzxyx' ? distinct chars: 3
  Right part: '' ? distinct chars: 0

Key Points

  • We use two Counter objects to track character frequencies in left and right parts

  • As we iterate through the string, we move characters from right to left

  • We delete entries with zero count to get the correct distinct character count

  • A good split occurs when both parts have the same number of distinct characters

Conclusion

This algorithm efficiently finds good splits by maintaining frequency counters for both parts of the string. The time complexity is O(n) where n is the length of the string, making it an optimal solution for this problem.

Updated on: 2026-03-25T20:59:49+05:30

426 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements