Nuts & Bolts Problem

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.

Lintcode上的一道题目,本身题目来源是geeksforgeeks。即是对两个数组进行配对排序,但是每个数组的自身元素不可以进行比较。

如果使用暴力方法,取其中一个数组,对该数组中的每个元素再另外一个数组中进行排序,则复杂度是O(n^2)的。优化方法是使用快速排序。即每次先用bolts数组的最后一个元素对nuts进行一个partition。则partition得到的中间元素就是和bolts数组最后一个元素对应的元素。用这个元素再对bolts元素做排序,则nuts和bolts数组中的划分位的元素是一对,且在数组中的位置一样。之后根据这个位置信息做递归进行循环处理。是一个交叠的快速排序过程。时间复杂度O(nlogn),代码如下:

 

# class Comparator:
#     def cmp(self, a, b)
# You can use Compare.cmp(a, b) to compare nuts "a" and bolts "b",
# if "a" is bigger than "b", it will return 1, else if they are equal,
# it will return 0, else if "a" is smaller than "b", it will return -1.
# When "a" is not a nut or "b" is not a bolt, it will return 2, which is not valid.
class Solution:
    # @param nuts: a list of integers
    # @param bolts: a list of integers
    # @param compare: a instance of Comparator
    # @return: nothing
    def sortNutsAndBolts(self, nuts, bolts, compare):
        if not nuts or not bolts:
            return
        if len(nuts) != len(bolts):
            return 
        self.quicksort(nuts, bolts, 0, len(nuts)-1, compare)
        return 
    
    def quicksort(self, nuts, bolts, low, high, compare):
        if low < high:
            index = self.partition(nuts, low, high, bolts[high], compare) #get the pivot nuts's index 
            self.partition(bolts, low, high, nuts[index], compare)  #the positions get aligned
            self.quicksort(nuts, bolts, low, index-1, compare)
            self.quicksort(nuts, bolts, index + 1, high, compare)
            
            
    def partition(self, arr,low, high, pivot, compare):
        i = low - 1
        j = low 
        while j < high:
            state1 = compare.cmp(arr[j], pivot)
            state2 = compare.cmp(pivot, arr[j])
            if state1 == -1 or state2 == 1:
                i += 1
                if i != j:
                    arr[i], arr[j] = arr[j], arr[i]
                j += 1
            elif state1 == 0 or state2 == 0:
                arr[j], arr[high] = arr[high], arr[j]
            else:
                j +=1 
        i += 1
        arr[i], arr[high] = arr[high], arr[i]
        
        return i        

值的注意的是compare类的cmp函数比的是nuts和bolts,而每次partition针对的是其中一个数组,所以pivot和数组不能明确知道哪个是nuts,哪个是bolts,需要都比较一下。

转载于:https://www.cnblogs.com/sherylwang/p/5656703.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值