4
4
class Solution {
5
5
public:
6
6
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
+ };
19
18
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);
24
22
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);
35
27
}
36
- }
37
28
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
+ };
40
39
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
+ }
43
46
}
44
47
};
45
48
@@ -49,49 +52,49 @@ class Solution {
49
52
class Solution_Generic {
50
53
public:
51
54
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
+
52
89
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
+ });
57
93
if (total % 2 == 1 ) {
58
94
return findKthInSortedArrays (arrays, total / 2 + 1 );
59
95
} else {
60
96
return (findKthInSortedArrays (arrays, total / 2 ) +
61
97
findKthInSortedArrays (arrays, total / 2 + 1 )) / 2.0 ;
62
98
}
63
99
}
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
- }
97
100
};
0 commit comments