螺絲螺母匹配問題(快排的變形應用)

題目:

給你一堆螺母和螺帽,每個螺母都有一個相對應的螺帽,但是他們之間的對應關係已經打亂。你可以比較螺母和螺帽的大小關係,但是你無法比較螺母和螺母的大小關係,你也無法比較螺帽和螺帽的大小關係。時間複雜度nlogn。

1.在nut數組拿一個,可以把bolt數組分爲比那個小的,比那個大的,還有一個匹配的3個部分。

2.在bolt中小的那堆那一個可以把nut分成比那個小的,比那個大的,還有一個匹配的3個部分。

3.這樣可以發現,現在數組產生兩對比配的螺母和螺釘和一隊小的螺釘和螺母,一隊大的螺釘和螺母。

如圖所示:

 因爲螺母螺釘的大小隻能通過匹配方式比較,同類型之間不能比較大小。

/**
 * class Comparator {
 *     public:
 *      int cmp(string a, string 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 {
public:
    /**
     * @param nuts: a vector of integers
     * @param bolts: a vector of integers
     * @param compare: a instance of Comparator
     * @return: nothing
     */
    void sortNutsAndBolts(vector<string> &nuts, vector<string> &bolts, Comparator compare) {
        // write your code here
        quickSort(nuts, bolts, 0, nuts.size()-1, compare);
    }
    
private:
    // Every where has Quick sort thinking
    void quickSort(vector<string> &a, vector<string> &b, int l, int r, Comparator compare) {
        
        // 找出一個分裂點,分別分裂a和b
        int mark, count=0;
        for (int i=l; i<=r; ++i) { 
            int t = compare.cmp(a[l], b[i]); // a's first compare with all b's
            if (t==0) mark = i; // a第一個元素和b相等元素, 最終會找到b中的最右邊的匹配
            else 
                if (t==1) ++count; // a第一個元素大於b中的元素的個數
        }
        swap(a[l], a[l+count]); // a的左半部分分配count個元素
        swap(b[mark],b[l+count]);// b的左半部分分出來count個元素
        mark = l+count; // mark就是相同的匹配了,mark就是中軸
        
        
        int i = l, j = r;
        while (i<mark && j>mark) {
            while (i<mark && compare.cmp(a[i], b[mark])==-1) ++i; // 小於的
            while (j>mark && compare.cmp(a[j], b[mark])==1) --j; // 大於的
            if (i<j) swap(a[i++], a[j--]);
        } // a分成兩部分
        i = l; j = r;
        while (i<mark && j>mark) {
            while (i<mark && compare.cmp(a[mark], b[i])==1) ++i;
            while (j>mark && compare.cmp(a[mark], b[j])==-1) --j;
            if (i<j) swap(b[i++], b[j--]);
        } // b分成兩部分
        if (l<mark) quickSort(a, b, l, mark-1, compare);
        if (r>mark) quickSort(a, b, mark+1, r, compare);
    }    
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章