medium Determine if Two Strings Are Close
Problem Statement:
Two strings are considered similar if you can make one string look like the other using the following two operations:
- Swap any two characters.
- For example, abde -> aedb (
eandbswapped).
- For example, abde -> aedb (
- Replace every occurrence of one character with another, and replace the other character with the first one.
- For example, acabbb -> bcbaaa (all a's turn into b's, and all b's turn into a's)
Given two strings, word1 and word2, return true if they can be made similar, otherwise return false.
Examples
Example 1:
- Input:
word1 = "aacbbc", word2 = "bbcaca" - Expected Output:
true - Justification: You can swap the 'a's and 'b's in
word2to make it "aacbcb", then swap the last two characters to matchword1.
Example 2:
- Input:
word1 = "xxyyzz", word2 = "zzxxyy" - Expected Output:
true - Justification: Swapping characters
'x'with'z'and then'z'with'y'inword2will make it "xxyyzz", which matchesword1.
Example 3:
- Input:
word1 = "aabbcc", word2 = "aabbc" - Expected Output:
false - Justification: The lengths of the two strings are different, so they can't be made to look the same.
Constraints:
- 1 <= word1.length, word2.length <= 105
- word1 and word2 contain only lowercase English letters.
Try it yourself
Try solving this question here:
🎯 STRICT STANDOUT: Why / worked+complexity / pattern+when-not / edge / drills — Determine if Two Strings Are Close medium
Why this concept exists (judgment layer)
Close strings: you may swap any chars and reassign frequencies among existing chars — so equality of character SETS and equality of sorted FREQUENCY MULTISETS are necessary and sufficient. Not plain anagram (anagram needs exact per-char counts).
Worked example with complexity derivation
word1=aacbbc, word2=bbcaca: both length 6; set {a,b,c}; counts (2,2,2) both → true.
cabbba / abbccc: sets {a,b,c}; counts sorted [1,2,3] both → true.
aabbcc / aabbc: lengths differ → false.
uau / ssx: sets differ → false even if freq multiset similar.
Pattern + when-NOT / named alternative
PATTERN: same alphabet support + same sorted frequency signature. WHEN NOT: need exact anagram → per-char counts equal (no sort of freqs). Edit distance / one swap only → different problem.
Edge case / failure mode
Edges: length 1; all identical chars; one char exclusive to one string; n=1e5 need O(n).
Hostile-panel drills (defend the decision)
Q1. Why sorted frequencies not raw arrays?
Model answer: Ops let you move counts between letters that exist; multiset of counts must match.
Q2. Why set equality required?
Model answer: Cannot invent a letter that never appears; swaps/reassign only among present chars.
Q3. Anagram vs close?
Model answer: Anagram ⇒ same counts per letter; close allows permuting the count values across letters.
✅ Solution Determine if Two Strings Are Close
Problem Statement:
Two strings are considered similar if you can make one string look like the other using the following two operations:
- Swap any two characters.
- For example, abde -> aedb (
eandbswapped).
- For example, abde -> aedb (
- Replace every occurrence of one character with another, and replace the other character with the first one.
- For example, acabbb -> bcbaaa (all a's turn into b's, and all b's turn into a's)
Given two strings, word1 and word2, return true if they can be made similar, otherwise return false.
Examples
Example 1:
- Input:
word1 = "aacbbc", word2 = "bbcaca" - Expected Output:
true - Justification: You can swap the 'a's and 'b's in
word2to make it "aacbcb", then swap the last two characters to matchword1.
Example 2:
- Input:
word1 = "xxyyzz", word2 = "zzxxyy" - Expected Output:
true - Justification: Swapping characters
'x'with'z'and then'z'with'y'inword2will make it "xxyyzz", which matchesword1.
Example 3:
- Input:
word1 = "aabbcc", word2 = "aabbc" - Expected Output:
false - Justification: The lengths of the two strings are different, so they can't be made to look the same.
Constraints:
- 1 <= word1.length, word2.length <= 105
- word1 and word2 contain only lowercase English letters.
Solution
To solve this problem, the first step is to ensure that both strings have the same length. If they don't, they can't be made similar. Next, we need to check if both strings have the same set of characters. If one string has a character that the other doesn't, they can't be made to look the same. Lastly, we check the frequency of each character. Both strings must have the same frequency distribution of characters for them to be transformable into one another.
This approach is effective because it simplifies the problem into three main checks: length, character set, and frequency distribution. By ensuring these conditions, we can determine if one string can be transformed into the other using the allowed operations.
Step-by-step Algorithm:
-
Check Lengths:
- If the lengths of
word1andword2are not the same, returnfalsebecause they cannot be transformed into each other.
- If the lengths of
-
Initialize Frequency Arrays and Character Sets:
- Create two integer arrays,
count1andcount2, each of size 26, to store the frequency of each character inword1andword2respectively. - Create two sets,
set1andset2, to store the unique characters present inword1andword2respectively.
- Create two integer arrays,
-
Fill Frequency Arrays and Character Sets:
- Iterate through each character in
word1, update its corresponding frequency incount1, and add the character toset1. - Iterate through each character in
word2, update its corresponding frequency incount2, and add the character toset2.
- Iterate through each character in
-
Sort Frequency Arrays:
- Sort
count1andcount2. Sorting helps to compare the character frequencies directly.
- Sort
-
Compare Frequency Arrays and Character Sets:
- Compare the sorted frequency arrays
count1andcount2. If they are not the same, returnfalse. - Compare the sets
set1andset2. If they are not the same, returnfalse.
- Compare the sorted frequency arrays
-
Return Result:
- If both the sorted frequency arrays and the character sets are the same, return
true.
- If both the sorted frequency arrays and the character sets are the same, return
Algorithm Walkthrough:
Let's walk through the algorithm using the example word1 = "aacbbc", word2 = "bbcaca".
-
Check Lengths:
- Length of
word1is 6. - Length of
word2is 6. - Both lengths are the same, so proceed to the next step.
- Length of
-
Initialize Frequency Arrays and Character Sets:
count1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]count2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]set1 = {}set2 = {}
-
Fill Frequency Arrays and Character Sets:
- For
word1:- 'a':
count1[0]becomes 1,set1becomes {'a'} - 'a':
count1[0]becomes 2,set1remains {'a'} - 'c':
count1[2]becomes 1,set1becomes {'a', 'c'} - 'b':
count1[1]becomes 1,set1becomes {'a', 'b', 'c'} - 'b':
count1[1]becomes 2,set1remains {'a', 'b', 'c'} - 'c':
count1[2]becomes 2,set1remains {'a', 'b', 'c'}
- 'a':
- For
word2:- 'b':
count2[1]becomes 1,set2becomes {'b'} - 'b':
count2[1]becomes 2,set2remains {'b'} - 'c':
count2[2]becomes 1,set2becomes {'b', 'c'} - 'a':
count2[0]becomes 1,set2becomes {'a', 'b', 'c'} - 'c':
count2[2]becomes 2,set2remains {'a', 'b', 'c'} - 'a':
count2[0]becomes 2,set2remains {'a', 'b', 'c'}
- 'b':
- For
-
Sort Frequency Arrays:
- Sorted
count1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2] - Sorted
count2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2]
- Sorted
-
Compare Frequency Arrays and Character Sets:
count1andcount2are equal after sorting.set1andset2are equal.
-
Return Result:
- Since both the sorted frequency arrays and character sets are the same, return
true.
- Since both the sorted frequency arrays and character sets are the same, return
Code
import java.util.*;
public class Solution {
public boolean closeStrings(String word1, String word2) {
if (word1.length() != word2.length()) {
return false; // The strings must be of equal length
}
int[] count1 = new int[26]; // Frequency of characters in word1
int[] count2 = new int[26]; // Frequency of characters in word2
Set<Character> set1 = new HashSet<>(); // Unique characters in word1
Set<Character> set2 = new HashSet<>(); // Unique characters in word2
for (char c : word1.toCharArray()) {
count1[c - 'a']++;
set1.add(c);
}
for (char c : word2.toCharArray()) {
count2[c - 'a']++;
set2.add(c);
}
Arrays.sort(count1); // Sort frequencies for comparison
Arrays.sort(count2); // Sort frequencies for comparison
return Arrays.equals(count1, count2) && set1.equals(set2);
}
public static void main(String[] args) {
Solution sol = new Solution();
// Example 1
System.out.println(sol.closeStrings("aacbbc", "bbcaca")); // true
// Example 2
System.out.println(sol.closeStrings("xxyyzz", "zzxxyy")); // true
// Example 3
System.out.println(sol.closeStrings("aabbcc", "aabbc")); // false
}
}
Complexity Analysis:
Time Complexity
The time complexity of this solution is count array takes constant time as its size is constant.
Space Complexity
The space complexity is
🎯 STRICT STANDOUT: Why / worked+complexity / pattern+when-not / edge / drills — Solution Determine if Two Strings Are Close
Why this concept exists (judgment layer)
Solution: length check, count[26]+sets, sort counts, compare. Elevation derives why sort(count) is O(1) (26) so total O(n), and names the algebraic invariant.
Worked example with complexity derivation
aacbbc / bbcaca:
count1 a2 b2 c2; count2 same; sets equal; sort equal → true.
Time: two O(n) scans + O(26 log 26) sort → Θ(n).
Space: O(1) extra (fixed 26) + set ≤26.
Counter: abc / abd — sets differ after counts may both be [1,1,1,0…].
Pattern + when-NOT / named alternative
PATTERN: frequency signature + alphabet support (hash/count arrays). WHEN NOT: unicode huge alphabet → HashMap counts not int[26]. When problem forbids frequency reassignment → require count1[c]==count2[c] all c.
Edge case / failure mode
Edges: a / a true; ab / aa false (freq multiset [1,1] vs [2]); hand-run aabbcc/aabbc length fail.
Hostile-panel drills (defend the decision)
Q1. Derive complexity.
Model answer: Θ(n) count + O(1) sort 26 ints → Θ(n) time, Θ(1) aux for lowercase English.
Q2. Could you skip sets if counts match after sort?
Model answer: No: support can differ with same sorted zero-padded multiset shapes — need set/support check.
Q3. abzz vs aazz?
Model answer: sets {a,b,z} vs {a,z}; counts [1,1,2] vs [2,2] — both checks fail appropriately.
Recognize it: Membership / frequency / “have I seen this?” in O(1) → a hash map or set.
▶ Visualize this problem (step it, predict each fork)
🤖 Don't fully get this? Learn it with Claude
Stuck on Determine if Two Strings Are Close? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Determine if Two Strings Are Close** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Determine if Two Strings Are Close** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Determine if Two Strings Are Close**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Determine if Two Strings Are Close**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.