Problem

You are given an array of strings words (0-indexed).

In one operation, pick two distinct indices i and j, where words[i] is a non-empty string, and move any character from words[i] to any position in words[j].

Return true _if you can makeevery string in _words equal using any number of operations,andfalse otherwise.

Examples

Example 1

1
2
3
4
5
Input: words = ["abc","aabc","bc"]
Output: true
Explanation: Move the first 'a' in words[1] to the front of words[2],
to make words[1] = "abc" and words[2] = "abc".
All the strings are now equal to "abc", so return true.

Example 2

1
2
3
Input: words = ["ab","a"]
Output: false
Explanation: It is impossible to make all the strings equal using the operation.

Constraints

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] consists of lowercase English letters.

Solution

Method 1 – Count and Check Divisibility

Intuition

If we can move any character to any string, all that matters is whether the total count of each character can be evenly divided among all strings.

Approach

  1. Count the total occurrences of each character in all strings.
  2. For each character, check if its count is divisible by the number of strings.
  3. If all are divisible, return true; otherwise, return false.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
public:
    bool makeEqual(vector<string>& words) {
        vector<int> cnt(26, 0);
        for (auto& w : words)
            for (char c : w) cnt[c - 'a']++;
        int n = words.size();
        for (int x : cnt) if (x % n) return false;
        return true;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func makeEqual(words []string) bool {
    cnt := make([]int, 26)
    for _, w := range words {
        for _, c := range w {
            cnt[c-'a']++
        }
    }
    n := len(words)
    for _, x := range cnt {
        if x%n != 0 {
            return false
        }
    }
    return true
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution {
    public boolean makeEqual(String[] words) {
        int[] cnt = new int[26];
        for (String w : words)
            for (char c : w.toCharArray()) cnt[c - 'a']++;
        int n = words.length;
        for (int x : cnt) if (x % n != 0) return false;
        return true;
    }
}
1
2
3
4
5
6
7
8
9
class Solution {
    fun makeEqual(words: Array<String>): Boolean {
        val cnt = IntArray(26)
        for (w in words) for (c in w) cnt[c - 'a']++
        val n = words.size
        for (x in cnt) if (x % n != 0) return false
        return true
    }
}
1
2
3
4
5
6
7
8
class Solution:
    def makeEqual(self, words: list[str]) -> bool:
        cnt = [0] * 26
        for w in words:
            for c in w:
                cnt[ord(c) - ord('a')] += 1
        n = len(words)
        return all(x % n == 0 for x in cnt)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
impl Solution {
    pub fn make_equal(words: Vec<String>) -> bool {
        let mut cnt = [0; 26];
        for w in words.iter() {
            for c in w.chars() {
                cnt[(c as u8 - b'a') as usize] += 1;
            }
        }
        let n = words.len();
        cnt.iter().all(|&x| x % n == 0)
    }
}
1
2
3
4
5
6
7
8
class Solution {
    makeEqual(words: string[]): boolean {
        const cnt = Array(26).fill(0);
        for (const w of words) for (const c of w) cnt[c.charCodeAt(0) - 97]++;
        const n = words.length;
        return cnt.every(x => x % n === 0);
    }
}

Complexity

  • ⏰ Time complexity: O(m), where m is the total number of characters in all words.
  • 🧺 Space complexity: O(1), since the alphabet size is constant (26).