题目:
给你一堆螺母和螺帽,每个螺母都有一个相对应的螺帽,但是他们之间的对应关系已经打乱。你可以比较螺母和螺帽的大小关系,但是你无法比较螺母和螺母的大小关系,你也无法比较螺帽和螺帽的大小关系。时间复杂度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);
}
};