Find Maximum Number of String Pairs

EASY

Description

You are given a 0-indexed array words consisting of distinct strings.

The string words[i] can be paired with the string words[j] if:

  • The string words[i] is equal to the reversed string of words[j].
  • 0 <= i < j < words.length.

Return the maximum number of pairs that can be formed from the array words.

Note that each string can belong in at most one pair.

 

Example 1:

Input: words = ["cd","ac","dc","ca","zz"]
Output: 2
Explanation: In this example, we can form 2 pair of strings in the following way:
- We pair the 0th string with the 2nd string, as the reversed string of word[0] is "dc" and is equal to words[2].
- We pair the 1st string with the 3rd string, as the reversed string of word[1] is "ca" and is equal to words[3].
It can be proven that 2 is the maximum number of pairs that can be formed.

Example 2:

Input: words = ["ab","ba","cc"]
Output: 1
Explanation: In this example, we can form 1 pair of strings in the following way:
- We pair the 0th string with the 1st string, as the reversed string of words[1] is "ab" and is equal to words[0].
It can be proven that 1 is the maximum number of pairs that can be formed.

Example 3:

Input: words = ["aa","ab"]
Output: 0
Explanation: In this example, we are unable to form any pair of strings.

 

Constraints:

  • 1 <= words.length <= 50
  • words[i].length == 2
  • words consists of distinct strings.
  • words[i] contains only lowercase English letters.

Approaches

Checkout 2 different approaches to solve Find Maximum Number of String Pairs. Click on different approaches to view the approach and algorithm in detail.

Brute-Force with Nested Loops

This approach iterates through all possible pairs of strings in the array and checks if they form a valid pair. A pair is valid if one string is the reverse of the other. To ensure each string is part of at most one pair, we use a boolean array to mark strings that have already been matched.

Algorithm

  • Initialize a counter pairs to 0.
  • Create a boolean array used of the same size as words, initialized to false. This will track which strings have already been paired.
  • Use a nested loop to iterate through all pairs of indices (i, j) such that 0 <= i < j < words.length.
  • In the outer loop, if used[i] is true, skip to the next i.
  • In the inner loop, if used[j] is true, skip to the next j.
  • For each pair (words[i], words[j]), check if words[i] is the reverse of words[j]. Since string length is 2, this means checking if words[i].charAt(0) == words[j].charAt(1) and words[i].charAt(1) == words[j].charAt(0).
  • If they form a pair, increment the pairs counter, mark both strings as used (used[i] = true, used[j] = true), and break the inner loop to find a pair for the next i.
  • Return the final pairs count.

We can solve this problem by systematically comparing every string with every other string that comes after it in the array.

We initialize a counter for the number of pairs to zero. To avoid pairing a string more than once, we use a boolean array, used, to keep track of which strings have already been included in a pair.

We use a nested loop. The outer loop iterates from i = 0 to n-1 (where n is the number of words), and the inner loop iterates from j = i + 1 to n-1. This structure ensures we only consider pairs (words[i], words[j]) where i < j.

Inside the loops, if both words[i] and words[j] have not been used yet, we check if words[i] is the reverse of words[j]. Since each string has a length of 2, reversing words[i] (e.g., "ab") is straightforward: we swap its two characters to get the reversed string (e.g., "ba").

If words[j] matches the reversed words[i], we've found a pair. We increment our pair counter and mark both words[i] and words[j] as used by setting used[i] and used[j] to true. We then break the inner loop for the current i because words[i] has found its unique partner.

After checking all possible pairs, the value of the counter is the maximum number of pairs.

class Solution {
    public int maximumNumberOfStringPairs(String[] words) {
        int n = words.length;
        int count = 0;
        boolean[] used = new boolean[n];

        for (int i = 0; i < n; i++) {
            if (used[i]) {
                continue;
            }
            for (int j = i + 1; j < n; j++) {
                if (used[j]) {
                    continue;
                }
                String s1 = words[i];
                String s2 = words[j];
                // Since length is 2, reversing is just swapping characters.
                if (s1.charAt(0) == s2.charAt(1) && s1.charAt(1) == s2.charAt(0)) {
                    count++;
                    used[i] = true;
                    used[j] = true;
                    break; // words[i] is now paired, move to the next i
                }
            }
        }
        return count;
    }
}

Complexity Analysis

Time Complexity: O(N^2), where N is the number of strings in `words`. The nested loops dominate the runtime. The operations inside the loop (character access and comparison) are constant time since the string length is fixed at 2.Space Complexity: O(N), where N is the number of strings in `words`. This is for the `used` boolean array.

Pros and Cons

Pros:
  • Simple and intuitive to understand.
  • Does not require complex data structures.
  • Low space overhead.
Cons:
  • Inefficient for large inputs due to the quadratic time complexity. While acceptable for the given constraints (N <= 50), it does not scale well.

Code Solutions

Checking out 3 solutions in different languages for Find Maximum Number of String Pairs. Click on different languages to view the code.


Video Solution

Watch the video walkthrough for Find Maximum Number of String Pairs



Data Structures:

ArrayHash TableString

Subscribe to Scale Engineer newsletter

Learn about System Design, Software Engineering, and interview experiences every week.

No spam, unsubscribe at any time.