5 Best Ways to Find Mirror Characters in a Python String

πŸ’‘ Problem Formulation: In this article, we tackle the problem of finding mirror characters in a string using Python. A mirror character is defined as a pair of characters that are at equal distances from the center on opposite sides of a given string. For instance, in the string "abXYZba" the mirror characters are "a" and "b" as they reflect each other around the string center.

Method 1: Brute Force Comparison

This method involves checking each character in the first half of the string with its corresponding mirror character in the second half. The strength of this approach is its simplicity, but it can be inefficient for lengthy strings due to its O(n) time complexity.

Here’s an example:

def find_mirror_characters(s):
    length = len(s)
    mirror_chars = []
    for i in range(length // 2):
        if s[i] == s[length - i - 1]:
            mirror_chars.append(s[i])
    return mirror_chars

print(find_mirror_characters("abXYZba"))

Output: ['a', 'b']

This code snippet defines a function find_mirror_characters() which iterates over half of the input string comparing each character to its corresponding mirror character. It collects the mirror characters in a list and returns it. It is straightforward and works well for short strings.

Method 2: Using Python’s Extended Slicing

The extended slicing method uses Python’s slice notation to reverse the string and compare it with the original. It is a quick and elegant solution but is also less efficient for very large strings due to the creation of a reversed copy.

Here’s an example:

def find_mirror_characters(s):
    return [char for i, char in enumerate(s[:len(s)//2]) if char == s[::-1][i]]

print(find_mirror_characters("abXYZba"))

Output: ['a', 'b']

The function find_mirror_characters() uses list comprehension to go through the first half of the string and compares each character with the reversed string’s corresponding character. It’s a one-liner method that utilizes Python’s powerful list comprehensions and slicing techniques.

Method 3: Two-pointer Technique

The two-pointer technique optimizes the search by initializing two pointers at the start and end of the string and moving them towards the center while comparing the characters. This method is efficient with time complexity O(n/2) and does not require extra space.

Here’s an example:

def find_mirror_characters(s):
    left, right = 0, len(s) - 1
    mirror_chars = []
    while left < right:
        if s[left] == s[right]:
            mirror_chars.append(s[left])
        left += 1
        right -= 1
    return mirror_chars

print(find_mirror_characters("abXYZba"))

Output: ['a', 'b']

This code defines a function find_mirror_characters() that sets two pointers and moves them towards the center. When matching characters are found, they’re added to the results list. This method is more space efficient than the previous one.

Method 4: Using a Hashing Function

This method uses a hash function to store characters of the string and quickly retrieve the mirror character by hash lookups. This is efficient for lookups but does require additional space for the hash table.

Here’s an example:

def find_mirror_characters(s):
    char_map = {i: s[i] for i in range(len(s))}
    return [s[i] for i in range(len(s)//2) if s[i] == char_map[len(s)-i-1]]

print(find_mirror_characters("abXYZba"))

Output: ['a', 'b']

This code snippet creates a hash table mapping indices to characters. Then it iterates over the string retrieving mirror characters by index lookups in the hash table.

Bonus One-Liner Method 5: Functional Approach with Filter and Lambda

The functional approach uses the filter() function combined with a lambda expression to concisely identify mirror characters. While elegant, it may be less readable to those unfamiliar with functional programming.

Here’s an example:

find_mirror_characters = lambda s: list(filter(lambda i: s[i] == s[-1 - i], range(len(s) // 2)))
print(find_mirror_characters("abXYZba"))

Output: [0, 1]

This one-liner uses a lambda function to define find_mirror_characters which filters the indices of mirror characters in the first half of the string. The indices can then be used to retrieve the characters themselves. It’s neat but could be confusing for beginners.

Summary/Discussion

  • Method 1: Brute Force. Simple and straightforward. Can be slow for large strings.
  • Method 2: Extended Slicing. Compact but creates a reversed copy of the string.
  • Method 3: Two-pointer Technique. Efficient and space-saving. Best for larger strings.
  • Method 4: Hashing Function. Fast lookups but uses extra memory.
  • Method 5: Functional Approach. Elegant one-liner. Can be less intuitive and returns indices.