-
Notifications
You must be signed in to change notification settings - Fork 0
/
4.median_of_two_sorted_arrays.java
107 lines (94 loc) · 2.82 KB
/
4.median_of_two_sorted_arrays.java
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
/**
* Resources: https://www.youtube.com/watch?v=lLFDQCDzfpI
* https://www.geeksforgeeks.org/merge-two-sorted-arrays/
*/
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
// Ensure nums1 is always shorter than nums2 for simplicity
if (nums1.length > nums2.length) {
int[] tmp = nums1;
nums1 = nums2;
nums2 = tmp;
}
// Init pointers for partitions.
// lo, will start at the first index
// hi, will start at the end of nums1 as if the first index of nums2
int lo = 0;
int hi = nums1.length;
int combinedLen = nums1.length + nums2.length;
// Loop until both pointers meet
while (lo <= hi) {
// nums1 being the shortest array, midX represents mid index of nums1
// midX = the mid index of nums1
// midY = the mid index of nums2
//
// Example 1
//
// nums1: [1, 3]
// ↑ midX
// nums2: [2]
// ↑ midY
//
// Combined sorted: [1, 2, 3]
// midX ↑ ↑ midY
//
// Example 2
//
// nums1: [1, 2]
// ↑ midX
// nums2: [3, 4]
// ↑ midY
//
// Combined sorted: [1, 2, 3, 4, 5]
// midx ↑ ↑ midY
//
// System.out.println("lo: " + lo + ",\t\t\thi: " + hi);
int midX = (lo + hi) / 2;
int midY = (combinedLen + 1) / 2 - midX;
// System.out.println("midX: " + midX + ",\t\tmidY: " + midY);
// getMax and getMin ensures that even when we are at the ends of the
// arrays, we still get a value that will not mess up the array while
// preventing index out of bounds.
int leftX = getMax(nums1, midX);
int rightX = getMin(nums1, midX);
// System.out.println("leftX: " + leftX + ",\trightX: " + rightX);
int leftY = getMax(nums2, midY);
int rightY = getMin(nums2, midY);
// System.out.println("leftY: " + leftY + ",\t\trightY: " + rightY);
// If both pointers crosses or met each other. Meaning we are at the
// middle of the combined sorted arrays.
if (leftX <= rightY && leftY <= rightX) {
// Handle even length
if (combinedLen % 2 == 0)
return (Math.max(leftX, leftY) + Math.min(rightX, rightY)) / 2.0;
else
return Math.max(leftX, leftY);
}
// Scoot over pointers if median not yet found
if (leftX > rightY)
hi = midX - 1;
else
lo = midX + 1;
}
// Return -1 if not sorted or failed
return -1;
}
// Returns the value BEFORE (let) the given idx or NEGATIVE_INFINITY if
// idx < 0
private int getMax(int[] nums, int idx) {
if (idx == 0) {
return (int)Double.NEGATIVE_INFINITY;
} else {
return nums[idx - 1];
}
}
// Returns the value AFTER (right) the given idx or POSITIVE_INFINITY if
// idx == nums.length
private int getMin(int[] nums, int idx) {
if (idx == nums.length) {
return (int)Double.POSITIVE_INFINITY;
} else {
return nums[idx];
}
}
}