Problem Walkthrough

Two Strings Close LeetCode 1657 Guide

Check that both strings share the same unique characters and that their sorted frequency lists match — two conditions that are necessary and sufficient to determine if one string can be transformed into the other.

8 min read|

Two Strings Close

LeetCode 1657

Problem Overview

LeetCode 1657 asks you to determine whether two strings word1 and word2 are "close." Two strings are close if you can transform one into the other using any number of the two allowed operations.

Operation 1 lets you swap any two characters in the string. You can swap any pair, not just adjacent ones, and you can do this as many times as you want. This means you can rearrange the string into any permutation freely.

Operation 2 lets you transform every occurrence of one character into another character and simultaneously transform every occurrence of that second character into the first. For example, transforming all "a"s to "b"s and all "b"s to "a"s at the same time. The goal is to determine if word1 can become word2 using any combination of these operations.

  • Operation 1 — swap any two characters anywhere in the string
  • Operation 2 — transform all occurrences of character x to y and all y to x simultaneously
  • You may apply either operation any number of times in any order
  • Determine if word1 can be transformed into word2 using these operations
  • Both strings consist only of lowercase English letters

Key Insight

The two operations together have a precise mathematical effect. Operation 1 (swap) gives you full control over character order — you can rearrange the string into any permutation. This means the positions of characters are irrelevant; only the frequency of each character matters.

Operation 2 (transform) lets you reassign which frequency belongs to which character. If word1 has "a" appearing 3 times and "b" appearing 2 times, you can use operation 2 to make "a" appear 2 times and "b" appear 3 times. You are shuffling the frequency values among the character slots.

This leads to two necessary and sufficient conditions: both strings must use exactly the same set of distinct characters, and the multiset of frequency values (sorted) must be identical. If either condition fails, no sequence of operations can bridge the gap.

💡

Two Conditions Are Enough

You don't need to simulate the operations at all. Just check two things: (1) same unique characters — same character set, and (2) same multiset of frequencies — the sorted list of frequency counts must match. Both conditions together are necessary and sufficient.

Why Same Character Set

Operation 2 can swap the frequencies between two characters, but it cannot introduce a character that does not already exist in the string. If word1 contains the character "z" but word2 does not, no sequence of swaps or transforms will ever produce a string without "z" from word1.

Similarly, operation 1 only rearranges existing characters — it cannot create or destroy characters. So the set of distinct characters present in both strings must be exactly equal for the strings to be close.

This check is straightforward: compute the set of unique characters in word1 and the set in word2, then verify they are equal. If word1 has any character that word2 lacks, or vice versa, the answer is immediately false.

  1. 1Compute set1 = set of unique characters in word1
  2. 2Compute set2 = set of unique characters in word2
  3. 3If set1 != set2, return False immediately
  4. 4Any character present in one string but absent in the other makes transformation impossible
  5. 5Operation 2 can only redistribute frequencies among characters already present in the string

Why Same Sorted Frequencies

Once you confirm the character sets match, the question becomes: can you assign the frequencies of word1 to the characters so they match word2? Operation 2 lets you swap the frequencies of any two existing characters. By chaining multiple applications of operation 2, you can permute the frequency assignments arbitrarily among the characters.

This means you can assign any frequency value to any character — as long as the bag (multiset) of frequency values is the same in both strings. If word1 has frequencies {a:3, b:2, c:1} and word2 has {a:1, b:3, c:2}, sorted both give [1, 2, 3] and they match.

If the sorted frequency lists differ, no amount of operation 2 applications can fix it — you cannot change the total count of any character, only redistribute which character holds which count. So the sorted multiset of frequency values must be identical.

ℹ️

Frequency Multiset Equivalence

The sorted frequency check captures multiset equivalence: since operation 2 can reassign any frequency value to any character (as long as that character exists in the string), only the bag of frequency values matters — not which character holds which frequency.

Walk-Through Example

Consider word1 = "aacabb" and word2 = "bbcbaa". For word1, count the characters: a appears 3 times, b appears 2 times, c appears 1 time — so freq1 = {a:3, b:2, c:1}. For word2: b appears 3 times, a appears 2 times, c appears 1 time — so freq2 = {b:3, a:2, c:1}.

Check condition 1: set of unique characters in word1 = {a, b, c}; set in word2 = {a, b, c}. They are equal, so the first condition passes. Now sort the frequency values: sorted(freq1.values()) = [1, 2, 3] and sorted(freq2.values()) = [1, 2, 3]. They match, so the second condition passes.

The answer is true. Intuitively, apply operation 2 to swap a and b in word1: now a appears 2 times and b appears 3 times, matching word2's frequency profile. Then use operation 1 to rearrange into "bbcbaa". Both operations together complete the transformation.

  1. 1word1="aacabb" → freq={a:3, b:2, c:1}, set={a,b,c}
  2. 2word2="bbcbaa" → freq={b:3, a:2, c:1}, set={a,b,c}
  3. 3Condition 1: {a,b,c} == {a,b,c} ✓ character sets match
  4. 4Condition 2: sorted [1,2,3] == sorted [1,2,3] ✓ frequency multisets match
  5. 5Result: True — word1 can be transformed into word2

Code Walkthrough: Python and Java

In Python, use Counter from collections to build frequency maps in O(n). Check set equality with set(counter1.keys()) == set(counter2.keys()). Then sort the values and compare: sorted(counter1.values()) == sorted(counter2.values()). The sort is O(26 log 26) since there are at most 26 distinct lowercase letters — effectively O(1). Overall time is O(n) and space is O(1) since the alphabet is bounded.

In Java, use a HashMap<Character, Integer> or an int array of size 26 for the frequency maps. Convert the frequency maps to arrays, sort them, and compare with Arrays.equals(). Check the character sets by verifying that every position in the int array is either both zero or both non-zero. The logic mirrors Python exactly.

A common optimization: first check if word1.length() != word2.length() and return false immediately — if they have different lengths, no rearrangement of characters can make them equal, so they cannot be close. This early exit avoids building frequency maps in the trivially false case.

⚠️

Check BOTH Conditions

You must verify both the character set equality AND the sorted frequency equality. Checking only one is not sufficient. Two strings can have the same sorted frequencies but different character sets (e.g., "aab" and "bbc" have sorted freqs [1,2] but different sets), or same character sets but different sorted frequencies — either alone will give wrong answers.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now