螺母和螺栓问题(锁和钥匙问题) |设置 1
给定一组 n 个不同尺寸的螺母和 n 个不同尺寸的螺栓。螺母和螺栓之间存在一对一的映射关系。高效匹配螺母和螺栓。
约束:不允许将一个螺母与另一个螺母或一个螺栓与另一个螺栓进行比较。这意味着螺母只能与螺栓进行比较,而螺栓只能与螺母进行比较,看哪个更大/更小。
问这个问题的另一种方法是,给定一个带有锁和钥匙的盒子,其中一把锁可以用盒子中的一把钥匙打开。我们需要匹配这对。
蛮力方法:从第一个螺栓开始,将其与每个螺母进行比较,直到找到匹配项。在最坏的情况下,我们需要 n 次比较。对所有螺栓执行此操作会给我们带来 O(n^2) 复杂度。
快速排序方式:我们可以使用快速排序技术来解决这个问题。为了理解逻辑,我们在字符数组中表示具体细节。
表示为字符数组的坚果
字符坚果[] = {'@', '#', '$', '%', '^', '&'}
表示为字符数组的螺栓
字符螺栓[] = {'$', '%', '&', '^', '@', '#'}
该算法首先通过选择 bolts 数组的最后一个元素作为枢轴来执行分区,重新排列螺母数组并返回分区索引“i”,使得所有小于 nut[i] 的螺母都在左侧,所有大于 nut 的螺母[i] 在右侧。接下来使用nuts[i],我们可以划分螺栓数组。分区操作可以很容易地在 O(n) 中实现。此操作还使螺母和螺栓阵列很好地分区。现在我们在螺母和螺栓的左右子阵列上递归地应用此分区。
当我们对螺母和螺栓都应用分区时,总时间复杂度平均为 ?(2*nlogn) = ?(nlogn)。
这里为了简单起见,我们总是选择最后一个元素作为枢轴。我们也可以进行随机快速排序。
下面是上述思想的实现:
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
输出:
Matched nuts and bolts are :
# $ % & @ ^
# $ % & @ ^