Mutating counts without cleanup
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Build confidence with an intuition-first walkthrough focused on hash map fundamentals.
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 make every string in words equal using any number of operations, and false otherwise.
Example 1:
Input: words = ["abc","aabc","bc"] Output: true Explanation: Move the first 'a' inwords[1] to the front of words[2], to makewords[1]= "abc" and words[2] = "abc". All the strings are now equal to "abc", so returntrue.
Example 2:
Input: words = ["ab","a"] Output: false Explanation: It is impossible to make all the strings equal using the operation.
Constraints:
1 <= words.length <= 1001 <= words[i].length <= 100words[i] consists of lowercase English letters.Problem summary: 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 make every string in words equal using any number of operations, and false otherwise.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map
["abc","aabc","bc"]
["ab","a"]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1897: Redistribute Characters to Make All Strings Equal
class Solution {
public boolean makeEqual(String[] words) {
int[] cnt = new int[26];
for (var w : words) {
for (char c : w.toCharArray()) {
++cnt[c - 'a'];
}
}
int n = words.length;
for (int v : cnt) {
if (v % n != 0) {
return false;
}
}
return true;
}
}
// Accepted solution for LeetCode #1897: Redistribute Characters to Make All Strings Equal
func makeEqual(words []string) bool {
cnt := [26]int{}
for _, w := range words {
for _, c := range w {
cnt[c-'a']++
}
}
n := len(words)
for _, v := range cnt {
if v%n != 0 {
return false
}
}
return true
}
# Accepted solution for LeetCode #1897: Redistribute Characters to Make All Strings Equal
class Solution:
def makeEqual(self, words: List[str]) -> bool:
cnt = Counter()
for w in words:
for c in w:
cnt[c] += 1
n = len(words)
return all(v % n == 0 for v in cnt.values())
// Accepted solution for LeetCode #1897: Redistribute Characters to Make All Strings Equal
impl Solution {
pub fn make_equal(words: Vec<String>) -> bool {
let mut cnt = std::collections::HashMap::new();
for word in words.iter() {
for c in word.chars() {
*cnt.entry(c).or_insert(0) += 1;
}
}
let n = words.len();
cnt.values().all(|&v| v % n == 0)
}
}
// Accepted solution for LeetCode #1897: Redistribute Characters to Make All Strings Equal
function makeEqual(words: string[]): boolean {
const cnt: Record<string, number> = {};
for (const w of words) {
for (const c of w) {
cnt[c] = (cnt[c] || 0) + 1;
}
}
const n = words.length;
return Object.values(cnt).every(v => v % n === 0);
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan the rest of the array looking for a match. Two nested loops give n × (n−1)/2 comparisons = O(n²). No extra space since we only use loop indices.
One pass through the input, performing O(1) hash map lookups and insertions at each step. The hash map may store up to n entries in the worst case. This is the classic space-for-time tradeoff: O(n) extra memory eliminates an inner loop.
Review these before coding to avoid predictable interview regressions.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.