Lintcode: 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.

其实是一种特别顺序的排序, 所以就用quicksort-partition, 不过比较的元素和设计互相patition, partition 的比较因为是有equals的, 所以得用三个指针遍历

/**
 * public class NBCompare {
 *     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.
*/
public class Solution {
    /**
     * @param nuts: an array of integers
     * @param bolts: an array of integers
     * @param compare: a instance of Comparator
     * @return: nothing
     */
    public void sortNutsAndBolts(String[] nuts, String[] bolts, NBComparator compare) {
        if (nuts == null || bolts == null) return;
        if (nuts.length != bolts.length) return;

        qsort(nuts, bolts, compare, 0, nuts.length - 1);
    }

    private void qsort(String[] nuts, String[] bolts, NBComparator compare, 
                       int l, int u) {
        if (l >= u) return;
        // find the partition index for nuts with bolts[u]
        int part_inx = partition(nuts, bolts[u], compare, l, u);
        // partition bolts with nuts[part_inx]
        partition(bolts, nuts[part_inx], compare, l, u);
        // qsort recursively
        qsort(nuts, bolts, compare, l, part_inx - 1);
        qsort(nuts, bolts, compare, part_inx + 1, u);
    }

    private int partition(String[] str, String pivot, NBComparator compare, 
                          int l, int u) {
        
        int low = l;
        int high = u;
        int i = low;
        while (i <= high) {
            if (compare.cmp(str[i], pivot) == -1 || 
                compare.cmp(pivot, str[i]) == 1) {
                swap(str, i, low);
                i++;
                low++;
            }
            else if (compare.cmp(str[i], pivot) == 1 || 
                compare.cmp(pivot, str[i]) == -1) {
                swap(str, i, high);
                high--;
            }
            else i++;
        }
        return low;
    }

    private void swap(String[] str, int l, int r) {
        String temp = str[l];
        str[l] = str[r];
        str[r] = temp;
    }
}

  考点: partition 的设计, pivot 的选择 , 另一方的排序通过nuts排好后的数组再排, partition 不仅 排序还返回了bolts的pivot

partition 三指针两头往中间碰撞, 快排类似于先序遍历 + 后序遍历构造 树时的数组的起始值与终结值的位置不应包含遍历过得值

原文地址:https://www.cnblogs.com/apanda009/p/7257179.html