LeetCode 2839 - Check if Strings Can be Made Equal With Operations I | ExpertFunda
Home LeetCode Solutions Strings LeetCode 2839
# 2839

Check if Strings Can be Made Equal With Operations I

● Easy String Array Two Pointer Index Swap
O(1) Time O(1) Space Java · Python · C++
📋

Problem Statement

You are given two strings s1 and s2, both of length 4, consisting of lowercase English letters.

You can apply the following operation on any of the two strings any number of times:

🔁
Choose any two indices i and j such that j - i = 2, then swap the two characters at those indices.

Return true if you can make the strings equal, and false otherwise.

Examples
Example 1
Inputs1 = "abcd", s2 = "cdab"
Outputtrue
Swap s1[0] and s1[2] → "cbad". Swap s1[1] and s1[3] → "cdab". Now s1 == s2.
Example 2
Inputs1 = "abcd", s2 = "dacb"
Outputfalse
No sequence of valid swaps can bring s1 equal to s2.
Constraints
  • s1.length == s2.length == 4
  • s1 and s2 consist only of lowercase English letters
💡

Intuition

The key constraint is j - i = 2. In a length-4 string that means only two possible swaps exist:

🔑
Swap 0 ↔ 2 (even group) and Swap 1 ↔ 3 (odd group). These two groups are completely independent — a character at an even index can never reach an odd index.
Index groups
Index labels
idx 0
idx 1
idx 2
idx 3
s[0]
s[1]
s[2]
s[3]
even group odd group

Characters at even positions (0,2) can only ever swap with each other. Same for odd positions (1,3).

Step-by-step: s1="abcd" → s2="cdab"
0
Initial state
s1
a
b
c
d
s2
c
d
a
b
1
Swap s1[0] ↔ s1[2]  "abcd" → "cbad"
s1
c
b
a
d

s1[0] = 'c' now matches s2[0] ✓

2
Swap s1[1] ↔ s1[3]  "cbad" → "cdab"
s1
c
d
a
b

All positions match s2 → return true ✓

🧠

Approach & Algorithm

Core Insight: Since only positions 2 apart can swap, even indices {0, 2} form one independent group and odd indices {1, 3} form another. Each group can only be in 2 possible states — original order or swapped.
Algorithm Steps
1
Check the even group {0, 2}

Do s1[0]==s2[0] && s1[2]==s2[2] (no swap needed) OR s1[0]==s2[2] && s1[2]==s2[0] (one swap needed)?

2
Check the odd group {1, 3}

Do s1[1]==s2[1] && s1[3]==s2[3] (no swap needed) OR s1[1]==s2[3] && s1[3]==s2[1] (one swap needed)?

3
Return the AND of both checks

Both groups must independently satisfy their condition. One failure means the strings can never be made equal.

Java Solution

Optimal — O(1) Direct Comparison
Java
class Solution {
    public boolean canBeEqual(String s1, String s2) {

        // ── Even group: positions 0 and 2 ──
        // Either already equal, or they can swap with each other
        boolean evenMatch =
            (s1.charAt(0) == s2.charAt(0) && s1.charAt(2) == s2.charAt(2)) ||
            (s1.charAt(0) == s2.charAt(2) && s1.charAt(2) == s2.charAt(0));

        // ── Odd group: positions 1 and 3 ──
        // Either already equal, or they can swap with each other
        boolean oddMatch =
            (s1.charAt(1) == s2.charAt(1) && s1.charAt(3) == s2.charAt(3)) ||
            (s1.charAt(1) == s2.charAt(3) && s1.charAt(3) == s2.charAt(1));

        return evenMatch && oddMatch;
    }
}
Alternative — Sort Groups
Java
class Solution {
    public boolean canBeEqual(String s1, String s2) {
        // Extract and sort each group — if sorted arrays match,
        // some permutation (via swaps) can make them equal
        char[] e1 = {s1.charAt(0), s1.charAt(2)};
        char[] e2 = {s2.charAt(0), s2.charAt(2)};
        char[] o1 = {s1.charAt(1), s1.charAt(3)};
        char[] o2 = {s2.charAt(1), s2.charAt(3)};

        Arrays.sort(e1); Arrays.sort(e2);
        Arrays.sort(o1); Arrays.sort(o2);

        return Arrays.equals(e1, e2) && Arrays.equals(o1, o2);
    }
}
Python (bonus)
Python
class Solution:
    def canBeEqual(self, s1: str, s2: str) -> bool:
        # sorted even group of s1 must match that of s2
        # same for odd group
        return (
            sorted([s1[0], s1[2]]) == sorted([s2[0], s2[2]]) and
            sorted([s1[1], s1[3]]) == sorted([s2[1], s2[3]])
        )
📊

Complexity Analysis

Approach Time Space Notes
Direct Comparison O(1) O(1) 4 char comparisons, zero allocations
Sort Groups O(1) O(1)* Allocates 4 char arrays — technically O(1) due to fixed size
HashMap frequency O(1) O(1)* Overkill — HashMap overhead for 2-element comparison
Brute force permutations O(1) O(1) Only 4 combos to check — works but verbose
⚖️

All Approaches — Pros & Cons

1

Direct Index Comparison Recommended

Compare even-group pairs directly with two boolean expressions, AND the results together.

✓ Zero allocations. Fastest possible. O(1) time and O(1) space. Reads exactly like the problem statement.

✗ Slightly verbose for larger string sizes (doesn't generalize beyond length 4 without modification).

2

Sort the Groups

Extract indices 0,2 and 1,3 from both strings into char arrays, sort and compare with Arrays.equals().

✓ Clean and easy to generalize to longer strings. Very readable for interviews.

✗ Allocates 4 temporary arrays. Arrays.sort on 2-element arrays is still function-call overhead vs direct comparison.

3

Brute Force — Try All Combinations

Generate all 4 possible combinations (even swapped/not × odd swapped/not) and check if any equals s2.

✓ Extremely easy to reason about and verify for correctness. No edge-case thinking needed.

✗ Verbose, creates temporary strings, hard to scale. Wastes computation covering already-equivalent logical paths.

4

HashMap / Frequency Count

Build frequency maps for characters at even positions in s1 vs s2, and same for odd positions; compare both maps.

✓ Scales well if string length grows or if the problem allowed more complex swaps across multiple positions.

✗ Massive overkill for this problem. HashMap object creation and hashing for 2-char comparison is ~100× heavier than a direct boolean check.

📈

Problem Stats

Easy
Difficulty
67%
Acceptance
O(1)
Time
O(1)
Space
🔑

Key Insight

Positions 0 & 2 form one swap group. Positions 1 & 3 form another. They are completely independent — verify each group separately.

evenOK = check {0,2}
oddOK = check {1,3}
return evenOK && oddOK
Continue Reading →