githubEdit

26. Isomorphic Strings

βœ… GFG solution to Isomorphic Strings: check if two strings have one-to-one character mapping using efficient array-based or hash map techniques. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

Given two strings s1 and s2 consisting of only lowercase English letters and of equal length, check if these two strings are isomorphic to each other.

If the characters in s1 can be changed to get s2, then two strings are isomorphic. A character must be completely swapped out for another character while maintaining the order of the characters. A character may map to itself, but no two characters may map to the same character.

πŸ“˜ Examples

Example 1

Input: s1 = "aab", s2 = "xxy"
Output: true
Explanation: Each character in s1 can be consistently mapped to a unique character in s2 
(a β†’ x, b β†’ y).

Example 2

Input: s1 = "aab", s2 = "xyz"
Output: false
Explanation: Same character 'a' in s1 maps to two different characters 'x' and 'y' in s2.

Example 3

πŸ”’ Constraints

  • $1 \le \text{s1.size()} = \text{s2.size()} \le 10^5$

βœ… My Approach

The optimal solution uses Two-Way Character Mapping with Arrays:

Bidirectional Mapping Validation

  1. Key Insight:

    • We need to ensure one-to-one mapping between characters.

    • This requires checking both directions: s1β†’s2 and s2β†’s1.

    • Use two arrays to track mappings in both directions.

  2. Two-Array Strategy:

    • map1[c]: stores which character in s2 that character c in s1 maps to.

    • map2[c]: stores which character in s1 that character c in s2 maps to.

    • Initialize both arrays with a sentinel value (e.g., 0 or -1).

  3. Validation Logic:

    • For each position i, check both directions:

      • If s1[i] already mapped but to different character β†’ return false

      • If s2[i] already mapped but from different character β†’ return false

      • Otherwise, establish bidirectional mapping

  4. Algorithm Steps:

    • Iterate through both strings simultaneously.

    • Check if current mapping is consistent in both directions.

    • If inconsistency found, return false immediately.

    • If loop completes without issues, return true.

Why This Works: Bidirectional checking ensures no two characters map to the same character and each character has at most one mapping.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the length of the strings. We make a single pass through both strings with constant time operations for each character.

  • Expected Auxiliary Space Complexity: O(1), as we use fixed-size arrays of 256 or 26 elements for character mappings, which is constant space regardless of input size.

πŸ§‘β€πŸ’» Code (C)

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Two Hash Maps Approach

πŸ’‘ Algorithm Steps:

  1. Use two unordered maps for bidirectional character mapping.

  2. For each character pair, check if mapping exists and is consistent.

  3. If s1[i] already maps to different character, return false.

  4. If s2[i] already mapped from different character, return false.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single pass with hash operations

  • Auxiliary Space: πŸ’Ύ O(k) - Where k is number of unique characters (max 26)

βœ… Why This Approach?

  • Clean and intuitive with hash maps

  • Easy to understand bidirectional mapping

  • Good for dynamic character sets

πŸ“Š 3️⃣ Vector-Based Mapping

πŸ’‘ Algorithm Steps:

  1. Use two vectors of size 26 for lowercase letters only.

  2. Initialize with -1 to indicate no mapping exists.

  3. Track which characters in s2 are already used.

  4. Validate consistency during single pass.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single traversal

  • Auxiliary Space: πŸ’Ύ O(1) - Fixed size vectors (26 elements)

βœ… Why This Approach?

  • Optimized for lowercase letters only

  • Clear separation of mapping and usage tracking

  • Similar to given reference solution

πŸ“Š 4️⃣ String as Mapping Storage

πŸ’‘ Algorithm Steps:

  1. Use two strings of size 256 initialized with 0.

  2. Store character mappings directly in string indices.

  3. Compare mappings for consistency.

  4. Update both mappings simultaneously.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear time traversal

  • Auxiliary Space: πŸ’Ύ O(1) - Fixed size strings

βœ… Why This Approach?

  • Compact representation using strings

  • Direct character storage in mapping

  • Efficient for all ASCII characters

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🎯 Two-Array Bidirectional

🟒 O(n)

🟒 O(1)

πŸš€ Most efficient, cache-friendly

πŸ”§ Fixed size for all ASCII

πŸ” Two Hash Maps

🟒 O(n)

🟑 O(k)

πŸ“– Clean and intuitive

πŸ”§ Hash map overhead

πŸ“Š Vector-Based

🟒 O(n)

🟒 O(1)

🎯 Optimized for lowercase

πŸ”§ Limited to 26 characters

πŸ”€ String Mapping

🟒 O(n)

🟒 O(1)

πŸ’Ύ Compact representation

πŸ”§ Less readable

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Optimal performance needed

πŸ₯‡ Two-Array Bidirectional

β˜…β˜…β˜…β˜…β˜…

πŸ“– Readability priority

πŸ₯ˆ Two Hash Maps

β˜…β˜…β˜…β˜…β˜…

πŸ”§ Lowercase only

πŸ₯‰ Vector-Based

β˜…β˜…β˜…β˜…β˜†

🎯 Competitive programming

πŸ… Two-Array Bidirectional

β˜…β˜…β˜…β˜…β˜…

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated