因为我们不考虑自己和自己的差值,所以我们只考虑对角线斜向上的那一半区域。这个区域的值是自下而上自左而右递增的。并且我们可以sort array并且很简单的求出最大和最小的distance,也就是说我们可以用和K Pairs一样的方法来做一道题。因为sorted的性质,我们可以看做m个长度为n的sorted list用priority queue一个一个取直到取到第k个,但是我们有类似Kth Smallest Element in Sorted Matrix的值域Binary Search的更好的方法。同样每次求出mid然后统计小于等于mid的值的数量c,如果c >= k,hi = mid; 如果c < k, lo = mid + 1。因为array的值是有规律的,我们只需要最多m + n的时间就可以求出,假设第一列有x个小于mid的数,那么第二列就一定有>= x个,我们只需要将行指针单调地向下移动即可,列指针也是单调地向右移动,所以总的时间不会超过m + n。时间复杂度T(v) = T(v / 2) + m + n,考虑m + n一般小于v, 时间复杂度O(v * log v), 代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int smallestDistancePair(vector<int>& nums, int k) { | |
sort(nums.begin(), nums.end()); | |
int len = nums.size(), lo = INT_MAX, hi = nums[len - 1] - nums[0]; | |
if (len < 2)return -1; | |
for (int i = 1; i < len; ++i) | |
lo = min(lo, nums[i] - nums[i - 1]); | |
while (lo < hi) | |
{ | |
int mid = lo + (hi - lo) / 2, c = count(nums, mid); | |
if (c >= k)hi = mid; | |
else lo = mid + 1; | |
} | |
return lo; | |
} | |
private: | |
int count(vector<int>& nums, int k) { | |
int n = nums.size(), i = 0, res = 0; | |
for (int j = 1; j < n; ++j) | |
{ | |
while (i < j && nums[j] - nums[i] > k)++i; | |
res += (j - i); | |
} | |
return res; | |
} | |
}; |
No comments:
Post a Comment