Nuts & Bolts (or Lock & Key) Problem

Last Updated : 7 Apr, 2026

Given a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping between nuts and bolts. Match nuts and bolts efficiently. Comparison of a nut to another nut or a bolt to another bolt is not allowed. The elements in output should follow the following order: { !,#,$,%,&,*,?,@,^ }

Input: , nuts[] = {@, %, $, #, ^}, bolts[] = {%, @, #, $ ^}
Output: # $ % @ ^

Explanation: As per the order # should come first after that $ then % then @ and ^.

Input: nuts[] = {^, &, %, @, #, *, $, ?, !}, bolts[] = {?, #, @, %, &, *, $ ,^, !}
Output: ! # $ % & * ? @ ^

Explanation: We'll have to match first ! then # , $, %, &, *, @, ^, ? as per the required ordering.

Try It Yourself
redirect icon

Quick sort is applied on nuts and bolts simultaneously — the last bolt acts as a pivot to partition nuts, then the matched nut partitions bolts. This cross-partitioning repeats recursively on left and right sub-arrays until all pairs are matched.

Here how it works:

1. Pick the last element of bolts[] as pivot and partition the nuts[] array around it, returning index i.
2. Use nuts[i] as the next pivot to partition the bolts[] array. Each partition runs in O(n).
3. Recur on the left and right sub-arrays of both nuts[] and bolts[] until all pairs are matched.

C++
#include <iostream>
using namespace std;

// Similar to standard partition method.
// Here we pass the pivot element too 
// instead of choosing it inside the method.
int partition(vector<char>& arr, int low, 
            int high, char pivot)
{
    int i = low;
    char temp1, temp2;
    
    for(int j = low; j < high; j++)
    {
        if (arr[j] < pivot)
        {
            temp1 = arr[i];
            arr[i] = arr[j];
            arr[j] = temp1;
            i++;
        } 
        else if(arr[j] == pivot)
        {
            temp1 = arr[j];
            arr[j] = arr[high];
            arr[high] = temp1;
            j--;
        }
    } 
    temp2 = arr[i];
    arr[i] = arr[high];
    arr[high] = temp2;

    // Return the partition index of 
    // an array based on the pivot 
    // element of other array.
    return i;
}

// Function which works just like quick sort
void matchPairs(vector<char>& nuts, vector<char>& bolts,
                int low, int high)
{
    if (low < high)
    {
        
        // Choose last character of bolts 
        // array for nuts partition.
        int pivot = partition(nuts, low, 
                            high, bolts[high]);

        // Now using the partition of nuts
        // choose that for bolts partition.
        partition(bolts, low, high, nuts[pivot]);

        // Recur for [low...pivot-1] & 
        // [pivot+1...high] for nuts and
        // bolts array.
        matchPairs(nuts, bolts, low, pivot - 1);
        matchPairs(nuts, bolts, pivot + 1, high);
    }
}

// Driver code
int main()
{
    
    // Nuts and bolts are represented 
    // as array of characters
    vector<char> nuts = {'@', '#', '$', '%', '^', '&'};
    vector<char> bolts = {'$', '%', '&', '^', '@', '#'};

    // Method based on quick sort which 
    // matches nuts and bolts
    matchPairs(nuts, bolts, 0, 5);

    cout <<"Matched nuts and bolts are : \n";
    
    for(int i = 0; i < nuts.size(); i++)
        cout << " " << nuts[i];
    cout << "\n";

   
}
C
// C program to solve nut and bolt 
// problem using Quick Sort.
#include<stdio.h>

// Method to print the array

// Similar to standard partition method.
// Here we pass the pivot element too 
// instead of choosing it inside the method.
int partition(char arr[], int low, 
              int high, char pivot)
{
    int i = low;
    char temp1, temp2;
    
    for(int j = low; j < high; j++)
    {
        if (arr[j] < pivot)
        {
            temp1 = arr[i];
            arr[i] = arr[j];
            arr[j] = temp1;
            i++;
        } 
        else if(arr[j] == pivot)
        {
            temp1 = arr[j];
            arr[j] = arr[high];
            arr[high] = temp1;
            j--;
        }
    } 
    temp2 = arr[i];
    arr[i] = arr[high];
    arr[high] = temp2;

    // Return the partition index of 
    // an array based on the pivot 
    // element of other array.
    return i;
}

// Function which works just like quick sort
void matchPairs(char nuts[], char bolts[],
                int low, int high)
{
    if (low < high)
    {
        
        // Choose last character of bolts 
        // array for nuts partition.
        int pivot = partition(nuts, low, 
                              high, bolts[high]);

        // Now using the partition of nuts
        // choose that for bolts partition.
        partition(bolts, low, high, nuts[pivot]);

        // Recur for [low...pivot-1] & 
        // [pivot+1...high] for nuts and
        // bolts array.
        matchPairs(nuts, bolts, low, pivot - 1);
        matchPairs(nuts, bolts, pivot + 1, high);
    }
}

// Driver code
int main()
{
    
    // Nuts and bolts are represented 
    // as array of characters
    char nuts[] = {'@', '#', '$', '%', '^', '&'};
    char bolts[] = {'$', '%', '&', '^', '@', '#'};
    
    int n = sizeof(nuts) / sizeof(nuts[0]);
    // Method based on quick sort which 
    // matches nuts and bolts
    matchPairs(nuts, bolts, 0, n-1);

    printf("Matched nuts and bolts are:\n");

    for (int i = 0; i < n; i++)
        printf("%c ", nuts[i]);
    
}
Java
// Java program to solve nut and bolt problem using Quick Sort
public class NutsAndBoltsMatch
{
    //Driver method
    public static void main(String[] args)
    {
        // Nuts and bolts are represented as array of characters
        char nuts[] = {'@', '#', '$', '%', '^', '&'};
        char bolts[] = {'$', '%', '&', '^', '@', '#'};

        // Method based on quick sort which matches nuts and bolts
        matchPairs(nuts, bolts, 0, 5);

        System.out.println("Matched nuts and bolts are : ");

        for (int i = 0; i < nuts.length; i++)
            System.out.print(nuts[i] + " ");
        System.out.println();


    }


    // Method which works just like quick sort
    private static void matchPairs(char[] nuts, char[] bolts, int low,
                                                              int high)
    {
        if (low < high)
        {
            // Choose last character of bolts array for nuts partition.
            int pivot = partition(nuts, low, high, bolts[high]);

            // Now using the partition of nuts choose that for bolts
            // partition.
            partition(bolts, low, high, nuts[pivot]);

            // Recur for [low...pivot-1] & [pivot+1...high] for nuts and
            // bolts array.
            matchPairs(nuts, bolts, low, pivot-1);
            matchPairs(nuts, bolts, pivot+1, high);
        }
    }

    // Similar to standard partition method. Here we pass the pivot element
    // too instead of choosing it inside the method.
    private static int partition(char[] arr, int low, int high, char pivot)
    {
        int i = low;
        char temp1, temp2;
        for (int j = low; j < high; j++)
        {
            if (arr[j] < pivot){
                temp1 = arr[i];
                arr[i] = arr[j];
                arr[j] = temp1;
                i++;
            } else if(arr[j] == pivot){
                temp1 = arr[j];
                arr[j] = arr[high];
                arr[high] = temp1;
                j--;
            }
        }
        temp2 = arr[i];
        arr[i] = arr[high];
        arr[high] = temp2;

        // Return the partition index of an array based on the pivot 
        // element of other array.
        return i;
    }
}
Python
# Python program to solve nut and bolt
# problem using Quick Sort.
from typing import List

# Similar to standard partition method.
# Here we pass the pivot element too
# instead of choosing it inside the method.
def partition(arr: List[str], low: int, high: int, pivot: str) -> int:
    i = low
    j = low
    while j < high:
        if (arr[j] < pivot):
            arr[i], arr[j] = arr[j], arr[i]
            i += 1
        elif (arr[j] == pivot):
            arr[j], arr[high] = arr[high], arr[j]
            j -= 1
        j += 1
    arr[i], arr[high] = arr[high], arr[i]

    # Return the partition index of
    # an array based on the pivot
    # element of other array.
    return i

# Function which works just like quick sort
def matchPairs(nuts: List[str], bolts: List[str], low: int, high: int) -> None:
    if (low < high):

        # Choose last character of bolts
        # array for nuts partition.
        pivot = partition(nuts, low, high, bolts[high])

        # Now using the partition of nuts
        # choose that for bolts partition.
        partition(bolts, low, high, nuts[pivot])

        # Recur for [low...pivot-1] &
        # [pivot+1...high] for nuts and
        # bolts array.
        matchPairs(nuts, bolts, low, pivot - 1)
        matchPairs(nuts, bolts, pivot + 1, high)

# Driver code
if __name__ == "__main__":

    # Nuts and bolts are represented
    # as array of characters
    nuts = ['@', '#', '$', '%', '^', '&']
    bolts = ['$', '%', '&', '^', '@', '#']

    n = len(nuts)

    # Match nuts and bolts
    matchPairs(nuts, bolts, 0, n - 1)

    # Print in main
    print("Matched nuts and bolts are:")

    for nut in nuts:
        print(nut, end=" ")
    

# This code is contributed by sanjeev2552
C#
// C# program to solve nut and
// bolt problem using Quick Sort 
using System;
using System.Collections.Generic;
    
class GFG 
{ 
    // Driver Code 
    public static void Main(String[] args) 
    { 
        // Nuts and bolts are represented 
        // as array of characters 
        char []nuts = {'@', '#', '$', '%', '^', '&'}; 
        char []bolts = {'$', '%', '&', '^', '@', '#'}; 

        int n = nuts.Length;

        // Match nuts and bolts
        matchPairs(nuts, bolts, 0, n - 1);

        // Print in Main
        Console.WriteLine("Matched nuts and bolts are:");

        foreach (char nut in nuts)
            Console.Write(nut + " ");
    } 

    // Method to print the array 
    private static void printArray(char[] arr) 
    { 
        foreach (char ch in arr)
        { 
            Console.Write(ch + " "); 
        } 
        Console.Write("\n"); 
    } 

    // Method which works just like quick sort 
    private static void matchPairs(char[] nuts, 
                                   char[] bolts, 
                                   int low, int high) 
    { 
        if (low < high) 
        { 
            // Choose last character of 
            // bolts array for nuts partition. 
            int pivot = partition(nuts, low, 
                                  high, bolts[high]); 

            // Now using the partition of nuts 
            // choose that for bolts partition. 
            partition(bolts, low, high, nuts[pivot]); 

            // Recur for [low...pivot-1] & 
            // [pivot+1...high] for nuts 
            // and bolts array. 
            matchPairs(nuts, bolts, low, pivot - 1); 
            matchPairs(nuts, bolts, pivot + 1, high); 
        } 
    } 

    // Similar to standard partition method. 
    // Here we pass the pivot element too 
    // instead of choosing it inside the method. 
    private static int partition(char[] arr, int low,
                                 int high, char pivot) 
    { 
        int i = low; 
        char temp1, temp2; 
        for (int j = low; j < high; j++) 
        { 
            if (arr[j] < pivot)
            { 
                temp1 = arr[i]; 
                arr[i] = arr[j]; 
                arr[j] = temp1; 
                i++; 
            } 
            else if(arr[j] == pivot)
            { 
                temp1 = arr[j]; 
                arr[j] = arr[high]; 
                arr[high] = temp1; 
                j--; 
            } 
        } 
        temp2 = arr[i]; 
        arr[i] = arr[high]; 
        arr[high] = temp2; 

        // Return the partition index of an array 
        // based on the pivot element of other array. 
        return i; 
    } 
} 

// This code is contributed by PrinciRaj1992
JavaScript
// JavaScript program to solve nut and
// bolt problem using Quick Sort


// QuickSort style matching
function matchPairs(nuts, bolts, low, high) {
    if (low < high) {

        // Partition nuts using bolt pivot
        let pivot = partition(nuts, low, high, bolts[high]);

        // Partition bolts using nut pivot
        partition(bolts, low, high, nuts[pivot]);

        // Recursively match left and right
        matchPairs(nuts, bolts, low, pivot - 1);
        matchPairs(nuts, bolts, pivot + 1, high);
    }
}


// Partition function
// Partition function
function partition(arr, low, high, pivot) {

    let i = low;
    let j = low;

    while (j < high) {

        if (arr[j] < pivot) {
            [arr[i], arr[j]] = [arr[j], arr[i]];
            i++;
            j++;
        }

        else if (arr[j] === pivot) {
            [arr[j], arr[high]] = [arr[high], arr[j]];
        }

        else {
            j++;
        }
    }

    [arr[i], arr[high]] = [arr[high], arr[i]];

    return i;
}


// Driver Code

let nuts = ['@', '#', '$', '%', '^', '&'];
let bolts = ['$', '%', '&', '^', '@', '#'];

let n = nuts.length;

// Match nuts and bolts
matchPairs(nuts, bolts, 0, n - 1);

// Print
console.log("Matched nuts and bolts are : \n" + nuts.join(" "));

Output
Matched nuts and bolts are : 
 # $ % & @ ^

Why we cannot use Hashing to solve this ?

If we use hashing, then we will have to compare nuts with nuts or bolts with bolts either while inserting into the hash and/or while printing the result in sorted order.


Comment