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.
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.
#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 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 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 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# 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 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.