Skip to content

Commit cdb330e

Browse files
authored
Update median-of-two-sorted-arrays.cpp
1 parent 79aa85b commit cdb330e

File tree

1 file changed

+71
-68
lines changed

1 file changed

+71
-68
lines changed

C++/median-of-two-sorted-arrays.cpp

Lines changed: 71 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,45 @@
44
class Solution {
55
public:
66
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
7-
if ((nums1.size() + nums2.size()) % 2 == 1) {
8-
return findKthInTwoSortedArrays(nums1, nums2, (nums1.size() + nums2.size()) / 2 + 1);
9-
} else {
10-
return (findKthInTwoSortedArrays(nums1, nums2, (nums1.size() + nums2.size()) / 2) +
11-
findKthInTwoSortedArrays(nums1, nums2, (nums1.size() + nums2.size()) / 2 + 1)) / 2.0;
12-
}
13-
}
14-
15-
int findKthInTwoSortedArrays(const vector<int>& A, const vector<int>& B,
16-
int k) {
17-
const int m = A.size();
18-
const int n = B.size();
7+
const auto& binary_search = [](int left, int right, const auto& check) {
8+
while (left <= right) {
9+
int mid = left + (right - left) / 2;
10+
if (check(mid)) {
11+
right = mid - 1;
12+
} else {
13+
left = mid + 1;
14+
}
15+
}
16+
return left;
17+
};
1918

20-
// Make sure m is the smaller one.
21-
if (m > n) {
22-
return findKthInTwoSortedArrays(B, A, k);
23-
}
19+
const auto& findKthInTwoSortedArrays = [&](auto& A, auto& B, int k) {
20+
int m = size(A);
21+
int n = size(B);
2422

25-
int left = 0;
26-
int right = m - 1;
27-
// Find a partition of A and B
28-
// where min left s.t. A[left] >= B[k - 1 - left]. Thus A[left] is the (k+1)-th or above element.
29-
while (left <= right) {
30-
int mid = left + (right - left) / 2;
31-
if (0 <= k - 1 - mid && k - 1 - mid < n && A[mid] >= B[k - 1 - mid]) {
32-
right = mid - 1;
33-
} else {
34-
left = mid + 1;
23+
// Make sure m is the smaller one.
24+
if (m > n) {
25+
swap(m, n);
26+
swap(A, B);
3527
}
36-
}
3728

38-
int Ai_minus_1 = left - 1 >= 0 ? A[left - 1] : numeric_limits<int>::min();
39-
int Bj = k - 1 - left >= 0 ? B[k - 1 - left] : numeric_limits<int>::min();
29+
// Find a partition of A and B
30+
// where min left s.t. A[left] >= B[k - 1 - left]. Thus A[left] is the (k+1)-th or above element.
31+
const int i = binary_search(0, min(m, k) - 1, [&](int i) {
32+
return 0 <= k - 1 - i && k - 1 - i < n && A[i] >= B[k - 1 - i];
33+
});
34+
// kth element would be A[i - 1] or B[k - 1 - i].
35+
int Ai_minus_1 = i - 1 >= 0 ? A[i - 1] : numeric_limits<int>::min();
36+
int Bj = k - 1 - i >= 0 ? B[k - 1 - i] : numeric_limits<int>::min();
37+
return max(Ai_minus_1, Bj);
38+
};
4039

41-
// kth element would be A[left - 1] or B[k - 1 - left].
42-
return max(Ai_minus_1, Bj);
40+
if ((size(nums1) + size(nums2)) % 2 == 1) {
41+
return findKthInTwoSortedArrays(nums1, nums2, (size(nums1) + size(nums2)) / 2 + 1);
42+
} else {
43+
return (findKthInTwoSortedArrays(nums1, nums2, (size(nums1) + size(nums2)) / 2) +
44+
findKthInTwoSortedArrays(nums1, nums2, (size(nums1) + size(nums2)) / 2 + 1)) / 2.0;
45+
}
4346
}
4447
};
4548

@@ -49,49 +52,49 @@ class Solution {
4952
class Solution_Generic {
5053
public:
5154
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
55+
const auto& binary_search = [](int left, int right, const auto& check) {
56+
while (left <= right) {
57+
int mid = left + (right - left) / 2;
58+
if (check(mid)) {
59+
right = mid - 1;
60+
} else {
61+
left = mid + 1;
62+
}
63+
}
64+
return left;
65+
};
66+
67+
const auto& findKthInSortedArrays = [&](const auto& arrays, int k) {
68+
const auto& check = [&](int num) {
69+
int res = 0;
70+
for (const auto array : arrays) {
71+
if (!array->empty()) { // count the number of values which are less or equal to num
72+
res += distance(array->cbegin(), upper_bound(array->cbegin(), array->cend(), num));
73+
}
74+
}
75+
return res >= k;
76+
};
77+
78+
int left = numeric_limits<int>::max();
79+
int right = numeric_limits<int>::min();
80+
for (const auto arr : arrays) {
81+
if (!empty(*arr)) {
82+
left = min(left, arr->front());
83+
right = max(right, arr->back());
84+
}
85+
}
86+
return binary_search(left, right, check);
87+
};
88+
5289
vector<vector<int> *> arrays{&nums1, &nums2};
53-
int total = accumulate(cbegin(arrays), cend(arrays), 0,
54-
[](const auto& x, const auto& y) {
55-
return x + size(*y);
56-
});
90+
int total = accumulate(cbegin(arrays), cend(arrays), 0, [](const auto& x, const auto& y) {
91+
return x + size(*y);
92+
});
5793
if (total % 2 == 1) {
5894
return findKthInSortedArrays(arrays, total / 2 + 1);
5995
} else {
6096
return (findKthInSortedArrays(arrays, total / 2) +
6197
findKthInSortedArrays(arrays, total / 2 + 1)) / 2.0;
6298
}
6399
}
64-
65-
private:
66-
int findKthInSortedArrays(const vector<vector<int> *>& arrays, int k) {
67-
int left = numeric_limits<int>::max();
68-
int right = numeric_limits<int>::min();
69-
for (const auto array : arrays) {
70-
if (!empty(*array)) {
71-
left = min(left, array->front());
72-
right = max(right, array->back());
73-
}
74-
}
75-
// left xxxxxxxooooooo right, find first xo or oo
76-
while (left <= right) {
77-
const auto mid = left + (right - left) / 2;
78-
if (check(arrays, mid, k)) {
79-
right = mid - 1;
80-
} else {
81-
left = mid + 1;
82-
}
83-
}
84-
return left;
85-
}
86-
87-
bool check(const vector<vector<int> *>& arrays, int num, int target) {
88-
int res = 0;
89-
for (const auto array : arrays) {
90-
if (!array->empty()) { // count the number of values which are less or equal to num
91-
res += distance(array->cbegin(),
92-
upper_bound(array->cbegin(), array->cend(), num));
93-
}
94-
}
95-
return res >= target;
96-
}
97100
};

0 commit comments

Comments
 (0)