-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
111 lines (99 loc) · 3.2 KB
/
main.cpp
File metadata and controls
111 lines (99 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Source: https://leetcode.com/problems/median-of-two-sorted-arrays
// Title: Median of Two Sorted Arrays
// Difficulty: Hard
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return **the median** of the two sorted arrays.
//
// The overall run time complexity should be `O(log (m+n))`.
//
// **Example 1:**
//
// ```
// Input: nums1 = [1,3], nums2 = [2]
// Output: 2.00000
// Explanation: merged array = [1,2,3] and median is 2.
// ```
//
// **Example 2:**
//
// ```
// Input: nums1 = [1,2], nums2 = [3,4]
// Output: 2.50000
// Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
// ```
//
// **Constraints:**
//
// - `nums1.length == m`
// - `nums2.length == n`
// - `0 <= m <= 1000`
// - `0 <= n <= 1000`
// - `1 <= m + n <= 2000`
// - `-10^6 <= nums1[i], nums2[i] <= 10^6`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <vector>
using namespace std;
// Merge, O(n)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int mn = nums1.size() + nums2.size();
auto nums = vector<int>(mn);
merge(nums1.cbegin(), nums1.cend(), nums2.cbegin(), nums2.cend(), nums.begin());
return double(nums[(mn - 1) / 2] + nums[mn / 2]) / 2;
}
};
// Binary search
//
// Denote the two arrays as A and B.
//
// Finding medium means to spit the array into two equal-sized partition,
// Where the maximum of the left part is less than the minimum of the right part.
//
// Use binary search on the shorter array (WLOG, say A).
// Say we split A at i, then B is automatically split at j = half - i.
// Denote A_l = A[i-1], A_r = A[i], B_l = B[j-1], B_r = B[j]. (Assign +-inf for out of bound values.)
// The partition is valid iff A_l <= B_r and B_l <= A_r.
//
// For final answer, if the array size is
// odd: ans = max(A_l, B_l)
// even: ans = (max(A_l, B_l) + min(A_r, B_r)) / 2
class Solution2 {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size();
int n2 = nums2.size();
int n = n1 + n2;
int half = (n + 1) / 2; // ensure left part is larger
const int INF = 1e7;
// WLOG, assume n1 < n2
if (n1 > n2) {
swap(n1, n2);
swap(nums1, nums2);
}
// Binary search
auto lo = 0, hi = n1 + 1; // [0, n1] unknown
while (lo < hi) {
auto mid1 = lo + (hi - lo) / 2;
auto mid2 = half - mid1;
auto left1 = (mid1 <= 0) ? -INF : nums1[mid1 - 1];
auto left2 = (mid2 <= 0) ? -INF : nums2[mid2 - 1];
auto right1 = (mid1 >= n1) ? INF : nums1[mid1];
auto right2 = (mid2 >= n2) ? INF : nums2[mid2];
if (left1 <= right2 && left2 <= right1) {
auto left = max(left1, left2);
auto right = min(right1, right2);
return (n % 2) ? left : double(left + right) / 2;
}
if (left1 > right2) {
hi = mid1; // [0, mid)
} else {
lo = mid1 + 1; // [mid+1, hi)
}
}
return {}; // unreachable
}
};