- 问题描述:假设我们有n个直径各不相同的螺钉以及n个相应的螺母。我们一次只能比较一对螺钉和螺母,来判断螺母是大于螺钉、小于螺钉还是正好适合螺钉。然而,我们不能拿两个螺母做比较,也不能拿两个螺钉做比较。我们的问题是要找到每一对匹配的螺钉和螺母。为该问题设计一个算法,它的平均效率必须属于集合O(n*logn)。
通常来说,看到平均效率O(n*logn),一般都会想到是快速排序。
如果有不会快速排序的可以看上一篇文章 点击这里跳转。
- 知道用快速排序,但是应该如何实现呢?本文来讲解一下up主的思路:
首先把螺母定义为Nut数组[6, 8, 1, 2, 9, 3, 7],螺钉定义为Screw数组[9, 3, 7, 1, 6, 2, 8];
螺母(Nut) 排序前:[6, 8, 1, 2, 9, 3, 7]
螺钉(Screw)排序前:[9, 3, 7, 1, 6, 2, 8]
-
首先从螺母(Nut)中随机取一个数(默认第一个元素 6 ),以该数作为螺钉(Screw)的基数去进行一次快速排序:
① 假设该基准元素位于最后一位,i j 同时从首个元素出发,j 从第一个元素开始向后寻找比基准小或基准元素:
(1) 当 j 位置的元素小于基准元素,则 i j 的元素交换,i 往后移动一位,j 继续往后寻找;
(2) 当 j 位置的元素等于基准元素,则 j 所在的与最后一位元素进行交换,j 从当前位置继续往后寻找;
(3) 当 j 位置的元素大于基准元素,则 j 继续往后寻找;
② 直到 j == right 时,交换 i j 所在的元素,返回 i ,一次排序结束。 -
从螺钉(Screw)中选择进行一次排序返回的基准元素,作为螺母(Nut)的基准元素去对螺母进行一次快速排序:(同以上步骤)
① 假设该基准元素位于最后一位,i j 同时从首个元素出发,j 从第一个元素开始向后寻找比基准小或基准元素:
(1) 当 j 位置的元素小于基准元素,则 i j 的元素交换,i 往后移动一位,j 继续往后寻找;
(2) 当 j 位置的元素等于基准元素,则 j 所在的与最后一位元素进行交换,j 从当前位置继续往后寻找;
(3) 当 j 位置的元素大于基准元素,则 j 继续往后寻找;
② 直到 j == right 时,交换 i j 所在的元素,返回 i ,一次排序结束。
根据以上步骤,将基准元素左、右的部分数组再次进行排序,直到数组有序
由于两个数组中的元素是1:1匹配的,所以当两个数组有序之后,螺母与螺钉的匹配问题也就解决了。
- 代码以下:
import java.util.*;
public class Main{
static int k=1;
public static void main(String[] args){
int[] Nut = {