Placement Prep

Find All Symmetric Pairs in an Array

Two approaches to find all symmetric pairs in an array: O(n^2) brute force and O(n) HashMap, with working C++, Python, and Java code.

By FACE Prep Team 6 min read
arrays hash-map data-structures coding-interview time-complexity python cpp

Two pairs (a, b) and (c, d) are symmetric when a == d and b == c. The problem is to find all such pairs in a given array. It shows up in hash-map sections of coding screens because it tests one specific skill: recognising when a look-up table eliminates the need for a nested loop.

What Makes Two Pairs Symmetric?

The definition is compact. Given a 2D array where each element is a pair of integers, two pairs at different positions are symmetric if swapping the values of one produces the other.

Consider this canonical input:

arr = { {1, 2}, {3, 4}, {5, 6}, {2, 1}, {4, 3}, {10, 11} }

Checking each pair manually:

  • (1, 2) and (2, 1): swap gives (2, 1), which is in the array. Symmetric.
  • (3, 4) and (4, 3): swap gives (4, 3), which is in the array. Symmetric.
  • (5, 6): the pair (6, 5) is absent. Not symmetric.
  • (10, 11): the pair (11, 10) is absent. Not symmetric.

Expected output:

(1, 2) and (2, 1) are symmetric
(3, 4) and (4, 3) are symmetric

Verify every implementation against this example before moving to edge cases.

Method 1: Brute Force with Nested Loops

The direct reading of the problem leads naturally to a nested-loop solution. For each pair at index i, scan every subsequent pair at index j to check whether the two are symmetric.

Algorithm steps

  • Start the outer loop at index i = 0.
  • Start the inner loop at index j = i + 1 (avoids double-counting and self-comparison).
  • For each combination, check two conditions: arr[i][0] == arr[j][1] AND arr[i][1] == arr[j][0].
  • If both hold, the pair at i and the pair at j are symmetric.

C++ implementation

#include <iostream>
#include <vector>
using namespace std;

void findSymmetricPairsBrute(vector<pair<int,int>>& arr) {
    int n = arr.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (arr[i].first  == arr[j].second &&
                arr[i].second == arr[j].first) {
                cout << "(" << arr[i].first  << "," << arr[i].second
                     << ") and ("
                     << arr[j].first  << "," << arr[j].second
                     << ") are symmetric\n";
            }
        }
    }
}

int main() {
    vector<pair<int,int>> arr = {
        {1,2},{3,4},{5,6},{2,1},{4,3},{10,11}
    };
    findSymmetricPairsBrute(arr);
    return 0;
}

Output:

(1,2) and (2,1) are symmetric
(3,4) and (4,3) are symmetric

Python implementation

def find_symmetric_pairs_brute(pairs):
    n = len(pairs)
    for i in range(n):
        for j in range(i + 1, n):
            if pairs[i][0] == pairs[j][1] and pairs[i][1] == pairs[j][0]:
                print(f"({pairs[i][0]},{pairs[i][1]}) and "
                      f"({pairs[j][0]},{pairs[j][1]}) are symmetric")

pairs = [(1,2),(3,4),(5,6),(2,1),(4,3),(10,11)]
find_symmetric_pairs_brute(pairs)

Complexity

  • Time: O(n^2) — for n = 6 pairs, the loop runs 15 comparisons (n*(n-1)/2 = 6*5/2). For n = 100, that is 4,950. For n = 10,000, it is 49,995,000.
  • Space: O(1) — no auxiliary data structure beyond loop variables.

The O(1) space is attractive, but the quadratic growth in comparisons makes this approach slow for any interview input above a few hundred pairs.

Method 2: HashMap in O(n) Time

The key observation: instead of searching for the symmetric partner on each iteration, store previously seen pairs in a hash map. When a new pair (a, b) arrives, check whether the map already holds an entry where key b maps to value a. If yes, (b, a) was seen earlier and the two are symmetric. If no, store a to b in the map and move on.

This reduces the problem to one left-to-right scan.

Algorithm steps

  • Create an empty hash map.
  • For each pair (a, b) in the array:
    • Look up key b in the map.
    • If the map contains key b and its value equals a: found a symmetric pair. Print it.
    • Otherwise: store a as key with b as value. Continue.

Step-by-step trace

StepPairMap lookupOutcome
1(1, 2)key 2 not in mapstore 1 to 2
2(3, 4)key 4 not in mapstore 3 to 4
3(5, 6)key 6 not in mapstore 5 to 6
4(2, 1)key 1 in map, value = 2print (1,2) and (2,1)
5(4, 3)key 3 in map, value = 4print (3,4) and (4,3)
6(10, 11)key 11 not in mapstore 10 to 11

Each pair is touched exactly once. The output matches the expected result.

C++ implementation

C++ provides unordered_map for O(1) average-case lookup and insertion:

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

void findSymmetricPairsHash(vector<pair<int,int>>& arr) {
    unordered_map<int, int> seen;
    for (auto& p : arr) {
        int a = p.first, b = p.second;
        auto it = seen.find(b);
        if (it != seen.end() && it->second == a) {
            cout << "(" << b << "," << a << ") and ("
                 << a << "," << b << ") are symmetric\n";
        } else {
            seen[a] = b;
        }
    }
}

int main() {
    vector<pair<int,int>> arr = {
        {1,2},{3,4},{5,6},{2,1},{4,3},{10,11}
    };
    findSymmetricPairsHash(arr);
    return 0;
}

Python implementation

Python’s built-in dict is an unordered hash map. The logic is identical:

def find_symmetric_pairs(pairs):
    seen = {}
    for a, b in pairs:
        if b in seen and seen[b] == a:
            print(f"({b},{a}) and ({a},{b}) are symmetric")
        else:
            seen[a] = b

pairs = [(1,2),(3,4),(5,6),(2,1),(4,3),(10,11)]
find_symmetric_pairs(pairs)

Java implementation

import java.util.HashMap;
import java.util.Map;

public class SymmetricPairs {
    static void findSymmetricPairs(int[][] arr) {
        Map<Integer, Integer> seen = new HashMap<>();
        for (int[] pair : arr) {
            int a = pair[0], b = pair[1];
            if (seen.containsKey(b) && seen.get(b).equals(a)) {
                System.out.println("(" + b + "," + a + ") and ("
                        + a + "," + b + ") are symmetric");
            } else {
                seen.put(a, b);
            }
        }
    }

    public static void main(String[] args) {
        int[][] arr = { {1,2},{3,4},{5,6},{2,1},{4,3},{10,11} };
        findSymmetricPairs(arr);
    }
}

One Java-specific detail: seen.get(b) returns a boxed Integer, not a primitive int. The .equals(a) call handles the comparison correctly. Relying on == with boxed integers works only for values in the cached range of -128 to 127; outside that range it compares object references, not values.

Complexity

  • Time: O(n) — one pass; each hash map operation is O(1) average.
  • Space: O(n) — the map can hold at most n entries in the worst case (no symmetric pairs at all).

Complexity Comparison

ApproachTimeSpaceSuitable for
Nested loopsO(n^2)O(1)n below 1,000
HashMap single passO(n)O(n)n into the millions

For any placement coding screen, the HashMap approach is the expected answer. Starting with brute force and explaining why it fails at scale is a good technique: it shows the interviewer that you understand the cost before you fix it.

Edge Cases

Three situations are worth testing before a submission:

Self-symmetric pairs

The pair (a, a) is symmetric with itself. A single occurrence in the array is stored in the map but not matched (no prior entry exists). A second occurrence of (a, a) triggers a match. Both methods handle this correctly by design.

No symmetric pairs

Input: {(1, 2), (3, 4), (5, 6)}. No pair has a symmetric partner. Both algorithms produce no output. This is valid and expected.

Duplicate non-symmetric pairs

If (a, b) appears twice and (b, a) also appears, the HashMap stores the first (a, b), then overwrites it if (b, a) has not appeared yet. Standard implementations assume distinct pairs. If the input can contain duplicates, extend the map to hold a list of values per key rather than a single value.

These cases connect directly to insert, delete, and search in an array and to finding the smallest and largest element. Both cover the array-operations groundwork that symmetric-pair detection builds on. The same two-index traversal also appears in matrix addition, subtraction, and multiplication, the cluster pillar for 2D array problems. For a wider set of hash-map and data-structure programs across C++, Java, and Python, the FACE Prep data structures programs collection covers the full scope.

The dict-based look-up behind the O(n) solution is the same pattern that powers LLM token caches and API response indexes. TinkerLLM is where you apply that instinct to real model interactions, starting at ₹299 with no subscription required.

Primary sources

Frequently asked questions

What are symmetric pairs in an array?

Two pairs (a, b) and (c, d) are symmetric when a equals d and b equals c. For example, (1, 2) and (2, 1) are symmetric because swapping the elements of either one produces the other.

What is the time complexity of the HashMap approach?

O(n) time and O(n) space, where n is the number of pairs. Each pair is processed in one left-to-right pass through the array; hash map lookups and inserts are O(1) on average.

Does the brute force approach work for large inputs?

It works but runs in O(n^2) time. For n = 10,000 pairs, that means up to 49,995,000 comparisons. The HashMap approach handles the same input in a single pass of 10,000 operations.

What happens when a pair is self-symmetric like (a, a)?

A single occurrence of (a, a) is not matched in the HashMap approach — the first time it appears, it is stored; no prior entry matches. Two occurrences of (a, a) will match on the second occurrence. Both approaches handle this correctly.

Is this problem asked in placement interviews?

Yes. It appears in the hash-map section of coding screens at service-tier companies. Interviewers typically expect you to start with the brute-force O(n^2) solution and then optimise to O(n) using a hash map within the same session.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF