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

Last Updated : 03 Nov, 2022

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 ` `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 ` ` `  `// 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

 ``

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)

Previous
Next