再做一百遍!
- [x] ### Many pointers CUT CUT CUT
https://blog.csdn.net/chen_xinjia/article/details/69258706
notebook Q48
4.Median of Two Sorted Arrays
There are two sorted arraysnums1andnums2of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
Time O(log(min(m,n)))
Space O(1)
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return findMedianSortedArrays(nums2, nums1);
}
int len = nums1.length + nums2.length;
int cut1 = 0;
int cut2 = 0;
int cutL = 0;
int cutR = nums1.length;
while (cut1 <= nums1.length) {
cut1 = cutL + (cutR - cutL) / 2;
cut2 = len / 2 - cut1;
double L1 = (cut1 == 0) ? Integer.MIN_VALUE : nums1[cut1 - 1];
double L2 = (cut2 == 0) ? Integer.MIN_VALUE : nums2[cut2 - 1];
double R1 = (cut1 == nums1.length) ? Integer.MAX_VALUE : nums1[cut1];
double R2 = (cut2 == nums2.length) ? Integer.MAX_VALUE : nums2[cut2];
if (L1 > R2) {
cutR = cut1 - 1;
}else if (L2 > R1){
cutL = cut1 + 1;
}else{
if (len % 2 == 0) {
return (Math.max(L1, L2) + Math.min(R1, R2)) / 2.0;
}else{
return Math.min(R1, R2);
}
}
}
return -1;
}
}
//Another java version without array copy. Should be easy to understand. Thanks for sharing the solution!
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
int left = (n + m + 1) / 2;
int right = (n + m + 2) / 2;
return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
}
private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
int len1 = end1 - start1 + 1;
int len2 = end2 - start2 + 1;
if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
if (len1 == 0) return nums2[start2 + k - 1];
if (k == 1) return Integer.min(nums1[start1], nums2[start2]);
int i = start1 + Integer.min(len1, k / 2) - 1;
int j = start2 + Integer.min(len2, k / 2) - 1;
//Eliminate half of the elements from one of the smaller arrays
if (nums1[i] > nums2[j]) {
return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
}
else {
return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
}
}