Open In App

Nuts & Bolts Problem (Lock & Key problem) using Quick Sort

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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. 
Constraint: Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means a nut can only be compared with a bolt and a bolt can only be compared with a nut to see which one is bigger/smaller.
Another way of asking this problem is, to give a box with locks and keys where one lock can be opened by one key in the box. We need to match the pair.
 

Recommended Practice

Brute force Way: Start with the first bolt and compare it with each nut until we find a match. In the worst case, we require n comparisons. Doing this for all bolts gives us O(n^2) complexity.
Quick Sort Way: We can use the quick sort technique to solve this. We represent nuts and bolts in a character array for understanding the logic.
Nuts represented as array of character 
char nuts[] = {‘@’, ‘#’, ‘$’, ‘%’, ‘^’, ‘&’}
Bolts represented as array of character 
char bolts[] = {‘$’, ‘%’, ‘&’, ‘^’, ‘@’, ‘#’}
This algorithm first performs a partition by picking last element of bolts array as a pivot, rearranging the array of nuts, and returns the partition index ‘i’ such that all nuts smaller than nuts[i] are on the left side and all nuts greater than nuts[i] are on the right side. Next using the nuts[i] we can partition the array of bolts. Partitioning operations can easily be implemented in O(n). This operation also makes nuts and bolts array nicely partitioned. Now we apply this partitioning recursively on the left and right sub-array of nuts and bolts.
As we apply to partition on both nuts and bolts so the total time complexity will be? (2*nlogn) = (nlogn) on average. 
Here for the sake of simplicity, we have chosen last element always as a pivot. We can do a randomized quick sort too. 
Below is the implementation of the above idea:
 

C++




// C++ program to solve nut and bolt 
// problem using Quick Sort.
#include <iostream>
using namespace std;
  
// Method to print the array
void printArray(char arr[])
{
    for(int i = 0; i < 6; i++)
    {
        cout << " " <<  arr[i];
    }
    cout << "\n";
}
  
// 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[] = {'$', '%', '&', '^', '@', '#'};
  
    // Method based on quick sort which 
    // matches nuts and bolts
    matchPairs(nuts, bolts, 0, 5);
  
    cout <<"Matched nuts and bolts are : \n";
      
    printArray(nuts);
    printArray(bolts);
}
  
// This code is contributed by shivanisinghss2110


C




// C program to solve nut and bolt 
// problem using Quick Sort.
#include<stdio.h>
  
// Method to print the array
void printArray(char arr[])
{
    for(int i = 0; i < 6; i++)
    {
        printf("%c ", arr[i]);
    }
    printf("\n");
}
  
// 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[] = {'$', '%', '&', '^', '@', '#'};
  
    // Method based on quick sort which 
    // matches nuts and bolts
    matchPairs(nuts, bolts, 0, 5);
  
    printf("Matched nuts and bolts are : \n");
      
    printArray(nuts);
    printArray(bolts);
}
  
// This code is contributed by Amit Mangal.


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 : ");
        printArray(nuts);
        printArray(bolts);
    }
  
    // Method to print the array
    private static void printArray(char[] arr) {
        for (char ch : arr){
            System.out.print(ch + " ");
        }
        System.out.print("\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;
    }
}


Python3




# Python program to solve nut and bolt
# problem using Quick Sort.
from typing import List
  
# Method to print the array
def printArray(arr: List[str]) -> None:
    for i in range(6):
        print(" {}".format(arr[i]), end=" ")
    print()
  
# 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 = ['$', '%', '&', '^', '@', '#']
  
    # Method based on quick sort which
    # matches nuts and bolts
    matchPairs(nuts, bolts, 0, 5)
    print("Matched nuts and bolts are : ")
    printArray(nuts)
    printArray(bolts)
  
# 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 = {'$', '%', '&', '^', '@', '#'}; 
  
        // Method based on quick sort 
        // which matches nuts and bolts 
        matchPairs(nuts, bolts, 0, 5); 
  
        Console.WriteLine("Matched nuts and bolts are : "); 
        printArray(nuts); 
        printArray(bolts); 
    
  
    // 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




<script>
  
// JavaScript program to solve nut and
// bolt problem using Quick Sort
      
  
    // Method to print the array
    function printArray(arr) 
    
        for (let ch = 0 ; ch < arr.length ; ch++)
        
            document.write(arr[ch] + " "); 
        
        document.write("<br>"); 
    
  
    // Method which works just like quick sort
    function matchPairs( nuts, bolts, low,  high) 
    
        if (low < high) 
        
            // Choose last character of
            // bolts array for nuts partition.
            var 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.
    function partition( arr,  low, high,  pivot) 
    
        var i = low; 
        var temp1, temp2; 
        for (var 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; 
    
      
        // Driver Code
  
        // Nuts and bolts are represented
        // as array of characters
        var nuts = ['@', '#', '$', '%', '^', '&']; 
        var bolts = ['$', '%', '&', '^', '@', '#']; 
  
        // Method based on quick sort
        // which matches nuts and bolts
        matchPairs(nuts, bolts, 0, 5); 
  
        document.write(
        "Matched nuts and bolts are : " + "<br>"
        ); 
        printArray(nuts); 
        printArray(bolts); 
   
  
  
</script>


Output:  

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

Time Complexity: O(N*logN), as we are using a loop to traverse N times in the partition function so it costs O(N) time and we are calling the partition function in each recursive call of matchPairs function which costs O(logN) time as in recursive call we divide the array into half. Where N is the length of the string.

Auxiliary Space: O(logN)
Nuts & Bolts Problem (Lock & Key problem) | Set 2 (Hashmap)

 



Last Updated : 03 Nov, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads