题目描述:
Given two array of integers(the first array is array A
, the second array is array B
), now we are going to find a element in array A which is A[i], and another element in array B which is B[j], so that the difference between A[i] and B[j] (|A[i] - B[j]|) is as small as possible, return their smallest difference.
For example, given array A = [3,6,7,4]
, B = [2,8,9,3]
, return 0
O(n log n) time
这题最简单的思路就是遍历两个数组,找到最小diff。题目的要求是O(nlogn)的时间复杂度,那么就会想到two pointers的做法:
1. 首先,two pointers做法一般都用在有序数组上,所以上来先把A和B排序;
2. 然后,将A中的element A[i]一个一个拿出来,跟B里的比较。这里不需要将B中的每一个element都拿来比较,其实最需要比的只是与A[i]相近的那些。由此我们可以利用有序数组的特点,做一个二分搜索,挑最重要的那些来比。比如,如果A[i]比B[mid]大,那么diff有可能更小的就只能在B[mid]之后的那些数。这里的code我就偷懒了,每次求得的mid都做一个min,其实对于每一个A[i], 真正需要比较的是B中最后一个比A[i]小,以及第一个比A[i]大的数。
Mycode(AC = 929ms):
class Solution {
public:
/**
* @param A, B: Two integer arrays.
* @return: Their smallest difference.
*/
int smallestDifference(vector<int> &A, vector<int> &B) {
// write your code here
sort(A.begin(), A.end()); // A = 3,4,6,7
sort(B.begin(), B.end()); // B = 2,4,8,9
int diff = INT_MAX;
for (int i = 0; i < A.size(); i++) { // A[i] = 4
int l = 0, r = B.size() - 1; // l = 0, r = 3
while (l < r) {
int mid = (l + r) / 2; // mid = 1
if (A[i] < B[mid]) {
r = mid - 1;
diff = min(diff, abs(A[i] - B[mid]));
}
else if (A[i] > B[mid]) {
l = mid + 1;
diff = min(diff, abs(A[i] - B[mid]));
}
else {
return 0;
}
}
if (l >= 0 && l < B.size()) {
diff = min(diff, abs(A[i] - B[l])); // diff = 1
}
}
return diff;
}
};