4. Median of Two Sorted Arrays
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
-106 <= nums1[i], nums2[i] <= 106
Solution:
Two Pointer:
Binary Search:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int len = len1 + len2;
if (len1 > len2){
return findMedianSortedArrays(nums2, nums1);
}
int left = 0;
int right = len1;
// value for the left right boundary of nums
int l1 = 0;
int r1 = 0;
int l2 = 0;
int r2 = 0;
while(left <= right){
int mid1 = left + (right - left)/2;
int mid2 = (len + 1)/ 2 - mid1; // 6 - 2 = 4
// 加 1 是为了处理当元素总数为奇数的情况,使得左半部分比右半部分多一个元素。无论总数是奇数还是偶数,这个分割线都能正确分割数组
// (m + n + 1) / 2 - i;
// 5 + 8 + 1 /2 -3
// 13+1 = 14 /2 = 7 - 3 = 4
if (mid1 == 0){
l1 = Integer.MIN_VALUE;
}else {
l1 = nums1[mid1 -1];
}
if (mid1 == len1){
r1 = Integer.MAX_VALUE;
}else {
r1 = nums1[mid1];
}
if (mid2 == 0){
l2 = Integer.MIN_VALUE;
}else{
l2 = nums2[mid2 - 1];
}
if (mid2 == len2){
r2 = Integer.MAX_VALUE;
}else{
r2 = nums2[mid2];
}
// check 是否满足正确的分割条件
if (l1 <= r2 && l2 <= r1){
if ((len) % 2 == 0){
return ((double) Math.max(l1, l2) + Math.min(r1, r2)) /2.0;
}else{
return Math.max(l1, l2);
}
}else if (l1 > l2){
right = mid1 - 1;
}else{
left = mid1 + 1;
}
}
return -1;
}
}
// TC: O(log(min(m,n)))
// SC: O(1)
嗯...两天啥也没干是吧...
I am back again
Back again 还是不会
Two Pointers:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] nums = new int[nums1.length + nums2.length];
int i = 0;
int j = 0;
int k = 0;
while (i < nums1.length && j < nums2.length){
if (nums1[i] < nums2[j]){
nums[k] = nums1[i];
k++;
i++;
}else {
nums[k] = nums2[j];
k++;
j++;
}
}
while(i < nums1.length){
nums[k] = nums1[i];
k++;
i++;
}
while(j < nums2.length){
nums[k] = nums2[j];
k++;
j++;
}
int mid = nums.length / 2;
if (nums.length % 2 == 0){
return (nums[mid - 1] + nums[mid] )/2.0;
}else{
return nums[mid];
}
}
}
// TC: O(n + m)
// SC: O(n + m)
虽然能过 但其实是不满足题意的
https://www.youtube.com/watch?v=q6IEA26hvXc
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int half = (nums1.length +nums2.length)/2;
if(nums2.length <nums1.length){
return findMedianSortedArrays(nums2,nums1);
}
int left = 0;
int right = nums1.length-1;
while(true){
int mid1 =(int)Math.floor((right+left)/2.0);
int mid2 = half -(mid1+1)-1;
int l1 = mid1>=0?nums1[mid1]:Integer.MIN_VALUE;
int l2 = mid2>=0?nums2[mid2]:Integer.MIN_VALUE;
int r1 = (mid1+1)<nums1.length?nums1[mid1+1]:Integer.MAX_VALUE;
int r2 = (mid2+1)<nums2.length?nums2[mid2+1]:Integer.MAX_VALUE;
if(l1<=r2 && l2<=r1 ){
//found it
if((nums1.length+nums2.length) %2 ==0){
return ((double)Math.max(l1,l2) +(double)Math.min(r1,r2))/2.0;
}else{
return Math.min(r1,r2);
}
}
else if(l1>r2){
right = mid1-1;
}else{
left = mid1+1;
}
}
}
}
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
// Ensure nums1 is the smaller array
if (nums2.length < nums1.length) {
return findMedianSortedArrays(nums2, nums1);
}
int totalLength = nums1.length + nums2.length;
int half = totalLength / 2;
l1
int left = 0;
int right = nums1.length - 1;
// Use 'while (left <= right)'
while (left <= right) {
int mid1 = left + (right - left) / 2;
int mid2 = half - (mid1 + 1) - 1;
int l1 = (mid1 >= 0) ? nums1[mid1] : Integer.MIN_VALUE;
int l2 = (mid2 >= 0) ? nums2[mid2] : Integer.MIN_VALUE;
int r1 = (mid1 + 1 < nums1.length) ? nums1[mid1 + 1] : Integer.MAX_VALUE;
int r2 = (mid2 + 1 < nums2.length) ? nums2[mid2 + 1] : Integer.MAX_VALUE;
// Check if correct partition is found
if (l1 <= r2 && l2 <= r1) {
if (totalLength % 2 == 0) {
return ((double) Math.max(l1, l2) + (double) Math.min(r1, r2)) / 2.0;
} else {
return Math.min(r1, r2);
}
} else if (l1 > r2) {
right = mid1 - 1; // Move left
} else {
left = mid1 + 1; // Move right
}
}
// When 'left' crosses 'right', handle the case where nums1 might be empty
int l1 = (left > 0 && left <= nums1.length) ? nums1[left - 1] : Integer.MIN_VALUE;
int l2 = (half - left - 1 >= 0) ? nums2[half - left - 1] : Integer.MIN_VALUE;
int r1 = (left < nums1.length) ? nums1[left] : Integer.MAX_VALUE;
int r2 = (half - left < nums2.length) ? nums2[half - left] : Integer.MAX_VALUE;
if (totalLength % 2 == 0) {
return ((double) Math.max(l1, l2) + (double) Math.min(r1, r2)) / 2.0;
} else {
return Math.min(r1, r2);
}
}
}