Skip to content
← All posts

Redistribute Characters to Make All Strings Equal: Frequency Divisibility Check

3 min read
leetcodeproblemeasystringshash-map

LeetCode 1897. Redistribute Characters to Make All Strings Equal sounds like it might involve complicated string manipulation. It does not. The key insight is that you can move any character from any string to any other string, as many times as you want. That freedom simplifies the problem enormously. You just need to check whether every character's total count divides evenly by the number of strings.

The problem

Given an array of strings words, you can pick any character from any string and move it to any position in any other string. Return true if you can make all strings equal using any number of moves.

Example: words = ["abc", "bca", "cab"]

There are 3 strings. Pooling all characters: a appears 3 times, b appears 3 times, c appears 3 times. Since 3 % 3 == 0 for every character, the answer is true. Each string can end up with one 'a', one 'b', and one 'c'.

words (n = 3):abcbcacabpool all charschar | count | % 3 == 0?'a'3yes'b'3yes'c'3yesAll counts divisible by 3. Return true.
Pool every character across all strings and count frequencies. If every count divides evenly by n, redistribution is possible.

The key insight

Because you can move characters freely between strings with no restrictions, the original arrangement does not matter at all. The only thing that matters is the total count of each character across all strings combined. If you have n strings and a character appears count times total, you need count to be divisible by n so that each string gets exactly count / n copies. If even one character fails this check, the answer is false.

Visual walkthrough

Step 1: Pool all characters from ["abc", "aaa", "bc"] where n = 3

input strings:abcaaabc

Combine every character from every string into one pool: a, b, c, a, a, a, b, c.

Step 2: Count every character

char | count | % 3 == 0?'a'4no'b'2no'c'2no

a appears 4 times, b appears 2 times, c appears 2 times.

Step 3: Check divisibility by n = 3

char | count | % 3 == 0?'a'4no'b'2no'c'2no4 % 3 != 0. Return false.

a has count 4, and 4 % 3 = 1, which is not zero. We cannot split 4 copies of 'a' evenly into 3 strings.

Step 4: A passing example with ["ab", "a", "b"]

'a'2yes'b'2yesAll counts divisible by 2. Return true.

a appears 2 times, b appears 2 times. Both 2 % 2 == 0. Return true.

The code

from collections import Counter

def make_equal(words: list[str]) -> bool:
    n = len(words)
    counts = Counter("".join(words))
    return all(c % n == 0 for c in counts.values())

Let's walk through what each line does:

  • n = len(words) stores the number of strings. This is the divisor we need to check against.
  • counts = Counter("".join(words)) concatenates all strings into one big string, then counts the frequency of every character. This gives us the pooled character counts.
  • return all(c % n == 0 for c in counts.values()) checks whether every character count is divisible by n. If any count has a nonzero remainder, we cannot distribute that character evenly, so we return False.

Complexity analysis

ComplexityWhy
TimeO(n * k)where n is the number of strings and k is the average string length, since we visit every character once
SpaceO(26) = O(1)the counter holds at most 26 lowercase English letters

The building blocks

This problem breaks down into two reusable pieces.

1. Frequency counting

Count how many times each element appears in a collection. This is the same brick used in Group Anagrams, First Unique Character in a String, and dozens of other hash map problems. The template is always the same:

from collections import Counter
counts = Counter(items)

2. Divisibility check

After counting, you verify a mathematical property on every count. Here the property is count % n == 0. This "check all values satisfy a condition" pattern shows up whenever you need to confirm that a distribution is possible. Python's all() with a generator expression is the clean way to write it.

Edge cases

  • Single string. If n == 1, every count is trivially divisible by 1. Return true immediately.
  • All strings already equal. The counts will all be divisible by n. The algorithm handles this without special logic.
  • Empty strings in the array. Empty strings contribute zero characters. They still count toward n, making it harder for counts to divide evenly. The algorithm handles this correctly.
  • All characters are the same. For example ["aaa", "aa", "a"]. The total count is 6, n is 3, and 6 % 3 == 0. Return true.

From understanding to recall

This problem feels almost too simple once you see the solution. "Just count characters and check divisibility." But the real skill is recognizing that free redistribution means you only need to care about totals, not positions. That leap from "I can move characters anywhere" to "I only need to check divisibility" is the insight worth drilling.

Spaced repetition helps you internalize that connection. CodeBricks breaks the problem into its two building blocks and presents them at increasing intervals. After a few review cycles, the moment you see "you can freely rearrange," your brain jumps straight to frequency counting and divisibility. No searching for the approach. You already have it.

Related posts