Nuts & Bolts Problem

本文探讨了在不允许直接比较两个螺母或两个螺栓的情况下,如何通过随机化快速排序算法变种解决螺母螺栓匹配问题。该算法能够在O(nlgn)的时间复杂度内完成匹配,并详细介绍了其实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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. Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means nut can only be compared with bolt and bolt can only be compared with nut to see which one is bigger/smaller.

We will give you a compare function to compare nut with bolt.

Example

Given nuts = ['ab','bc','dd','gg'], bolts = ['AB','GG', 'DD', 'BC'].

Your code should find the matching bolts and nuts.

one of the possible return:

nuts = ['ab','bc','dd','gg'], bolts = ['AB','BC','DD','GG'].

we will tell you the match compare function. If we give you another compare function.

the possible return is the following:

nuts = ['ab','bc','dd','gg'], bolts = ['BC','AA','DD','GG'].

So you must use the compare function that we give to do the sorting.

The order of the nuts or bolts does not matter. You just need to find the matching bolt for each nut.


Analysis: http://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/

There is a solution to this problem in O(nlgn) that works even if you can't compare two nuts or two bolts directly. That is without using a scale, or if the differences in weight are too small to observe.

It works by applying a small variation of randomised quicksort as follows:

Pick a random bolt b.
Compare bolt b with all the nuts, partitioning the nuts into those of size less than b and greater than b.
Now we must also partition the bolts into two halves as well and we can't compare bolt to bolt. But now we know what is the matching nut n to b. So we compare n to all the bolts, partitioning them into those of size less than n and greater than n.
The rest of the problem follows directly from randomised quicksort by applying the same steps to the lessThan and greaterThan partitions of nuts and bolts.

从这题得到的启发:如果一个本需要用O(N^2)来解决的问题,而被要求用更低的复杂度,应该想到需要减少compare的次数,怎么减少? partiton.

 1 /**
 2  * public class NBCompare {
 3  *     public int cmp(String a, String b);
 4  * }
 5  * You can use compare.cmp(a, b) to compare nuts "a" and bolts "b",
 6  * if "a" is bigger than "b", it will return 1, else if they are equal,
 7  * it will return 0, else if "a" is smaller than "b", it will return -1.
 8  * When "a" is not a nut or "b" is not a bolt, it will return 2, which is not valid.
 9 */
10 public class Solution {
11 
12     public void sortNutsAndBolts(String[] nuts, String[] bolts, NBComparator compare) {
13         // write your code here
14         if (nuts == null || bolts == null || nuts.length != bolts.length || compare == null) return;
15         helper(nuts, bolts, 0, nuts.length - 1, compare);
16     }
17     
18     public void helper(String[] nuts, String[] bolts, int start, int end, NBComparator c) {
19         if (start < end) {
20             int p = partition(nuts, bolts, start, end, c);
21             helper(nuts, bolts, start, p - 1, c);
22             helper(nuts, bolts, p + 1, end, c);
23         }
24     }
25     
26     
27     public int partition(String[] nuts, String[] bolts, int start, int end, NBComparator compare) {
28         int p = start;
29         for (int i = start; i < end; i++) {
30             if (compare.cmp(nuts[i], bolts[end]) < 0) {
31                 swap(nuts, p, i);
32                 p++;
33             } else if (compare.cmp(nuts[i], bolts[end]) == 0) {
34                 swap(nuts, i, end);
35                 i--;
36             }
37         }
38         
39         swap(nuts, p, end);
40         
41         int k = start;
42         for (int i = start; i < end; i++) {
43             if (compare.cmp(nuts[p], bolts[i]) > 0) {
44                 swap(bolts, k, i);
45                 k++;
46             } else if (compare.cmp(nuts[p], bolts[i]) == 0) {
47                 swap(bolts, i, end);
48                 i--;
49             }
50         }
51         swap(bolts, k, end);
52         
53         return k;
54     }
55     
56     public void swap(String[] arr, int i, int j) {
57         String temp = arr[i];
58         arr[i] = arr[j];
59         arr[j] = temp;
60     }
61 };

 

转载于:https://www.cnblogs.com/beiyeqingteng/p/5689975.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值