Skip to content

Commit

Permalink
Median of Two Sorted Arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
dksifoua committed Aug 28, 2024
1 parent 9da2cfe commit 59c9d17
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
|------|------------|------------------------------------------------|------------------------------------------------------|---------------------------------------------------------------------------|
| 0001 | Easy | Two Sum | Array, HashMap | [solution](./docs/0001-Two-Sum.md) |
| 0002 | Medium | Add Two numbers | LinkedList, Recursion | [solution](./docs/0002-Add-Two-Numbers.md) |
| 003 | Medium | Longest Substring Without Repeating Characters | Hash Table, String, Sliding Window | [solution](./docs/0003-Longest-Substring-Without-Repeating-Characters.md) |
| 0003 | Medium | Longest Substring Without Repeating Characters | Hash Table, String, Sliding Window | [solution](./docs/0003-Longest-Substring-Without-Repeating-Characters.md) |
| 0004 | Hard | Median of Two Sorted Arrays | Array, Binary Search, Divide and Conquer | [solution](./docs/0004-Median-of-Two-Sorted-Arrays.md) |
| 0011 | Medium | Container With Most Water | Array, Two Pointers, Greedy | [solution](./docs/0011-Container-With-Most-Water.md) |
| 0015 | Medium | Three sum | Array, Two Pointers, Sorting | [solution](./docs/0015-Three-Sum.md) |
| 0019 | Medium | Remove Nth Node From End Of List | Linked List, Two Pointers | [solution](./docs/0019-Remove-Nth-Node-From-End-Of-List.md) |
Expand Down
42 changes: 42 additions & 0 deletions docs/0004-Median-of-Two-Sorted-Arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# [Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/description/)

## Intuition

To find the median of two sorted arrays, we can take advantage of their sorted nature and avoid brute force merging and
sorting, which would result in an `O(m+n)` complexity. Instead, we aim to exploit binary search on one of the arrays to
reduce the time complexity to `O(log(min(m, n)))`. The intuition behind this approach is to partition the arrays into
two halves such that the left half contains the smaller elements, and the right half contains the larger elements. This
way, we can directly calculate the median based on the partitioning.

## Approach

1. **Recursive Handling of Array Sizes:** The function first ensures that we always perform the binary search on the
smaller array (`nums1`). This ensures the search space is minimized.
2. **Binary Search and Partitioning:** We calculate the middle index for `nums1` and determine the corresponding
partition index for `nums2`. The goal is to ensure that the elements in the left partitions of both arrays are
smaller than the elements in the right partitions.
3. **Conditions to Find the Median:**
- If the largest element in the left partition of `nums1` is smaller than or equal to the smallest element in the
right partition of `nums2`, and vice versa, then we have correctly partitioned the arrays.
- If the total length of both arrays is odd, the median is the maximum of the left partition.
- If the total length is even, the median is the average of the maximum of the left partition and the minimum of the
right partition.
4. **Adjusting the Partition:** If the current partitioning does not meet the conditions, the binary search is adjusted
by either moving the partition in `nums1` to the left or right, depending on the comparison of boundary elements.

## Complexity

- **Time Complexity: `O(log(min(m, n)))`**. The binary search is performed on the smaller array, so the time complexity
is logarithmic in the size of the smaller array.
- **Space Complexity: `O(1)`** as no additional space beyond a few variables is used.

## Code

- [Java](../src/main/java/io/dksifoua/leetcode/medianoftwosortedarrays/Solution.java)

## Summary

This solution uses a binary search technique to find the correct partitioning of two sorted arrays, allowing us to find
the median in `O(log(min(m, n))) time. By focusing on partitioning the arrays into equal halves and ensuring the left
half contains all smaller elements, we can calculate the median without merging the arrays. This method is efficient and
meets the problem’s time complexity requirement.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.dksifoua.leetcode.medianoftwosortedarrays;

public class Solution {

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return this.findMedianSortedArrays(nums2, nums1);
}

double median = 0d;
int totalLength = nums1.length + nums2.length;
int partitionSize = totalLength % 2 == 0 ? totalLength / 2 : 1 + totalLength / 2;
int leftIndex = 0, rightIndex = nums1.length - 1;
while (true) {
int middleIndex1 = Math.floorDiv(leftIndex + rightIndex, 2);
int middleIndex2 = partitionSize - (middleIndex1 + 1) - 1;

int leftElement1 = middleIndex1 >= 0 ? nums1[middleIndex1] : Integer.MIN_VALUE;
int leftElement2 = middleIndex2 >= 0 ? nums2[middleIndex2] : Integer.MIN_VALUE;
int rightElement1 = middleIndex1 + 1 < nums1.length ? nums1[middleIndex1 + 1] : Integer.MAX_VALUE;
int rightElement2 = middleIndex2 + 1 < nums2.length ? nums2[middleIndex2 + 1] : Integer.MAX_VALUE;

if (leftElement1 <= rightElement2 && leftElement2 <= rightElement1) {
if (totalLength % 2 > 0) {
median = Math.max(leftElement1, leftElement2);
} else {
median = (Math.max(leftElement1, leftElement2) + Math.min(rightElement1, rightElement2)) / 2d;
}
break;
}

if (leftElement1 > rightElement2) {
rightIndex = middleIndex1 - 1;
} else {
leftIndex = middleIndex1 + 1;
}
}

return median;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.dksifoua.leetcode.medianoftwosortedarrays;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class SolutionTest {

private final Solution solution = new Solution();

@Test
void test1() {
assertEquals(2d, solution.findMedianSortedArrays(new int[] { 1, 3 }, new int[] { 2 }));
}

@Test
void test2() {
assertEquals(2.5d, solution.findMedianSortedArrays(new int[] { 1, 2 }, new int[] { 3, 4 }));
}

@Test
void test3() {
assertEquals(1d, solution.findMedianSortedArrays(new int[] {}, new int[] { 1 }));
}

@Test
void test4() {
assertEquals(-1d, solution.findMedianSortedArrays(new int[] { 3 }, new int[] { -2, -1 }));
}
}

0 comments on commit 59c9d17

Please sign in to comment.