两个有序数组求中位数_递归分治_LeetCode_04
public class Test2 {
// 注意一些特殊情况如([],[1]),([1],[1]),([],[])
public double solve(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int totalLength = m + n;
int k = (m + n) / 2;
if (m == 0 && n == 0) {return 0;}
if (m == 0) return (totalLength % 2 == 0 ? (nums2[k]+nums2[k-1])/2.0 : nums2[k]);
if (n == 0) return (totalLength % 2 == 0 ? (nums1[k]+nums1[k-1])/2.0 : nums1[k]);
if (totalLength % 2 == 0) {
// 偶数 后面要除以2.0才能转换成double
return (recur(nums1, nums2, 0, 0, m, n, k) + recur(nums1, nums2, 0, 0, m, n, k+1)) / 2.0;
} else {
return recur(nums1, nums2, 0, 0, m, n, k+1);
}
}
// **区分第几个和索引的关系**
// 代表某一次递归, len1是较短的序列。k表示第k个,而不是索引
// k最小取值为1,表示第一个
public double recur(int[] nums1, int[] nums2, int start1, int start2, int len1, int len2, int k) {
if (len1 > len2) {
return recur(nums2, nums1, start2, start1, len2, len1, k);
}
// 递归终止条件
if (len1 == 0) {
return nums2[start2 + k - 1];
}
if (k == 1) {
return Math.min(nums1[start1], nums2[start2]);
}
// 区分索引和第几个,p,q代表第几个
// p + q = k - 1 两个序列下一个位置较小的一个即为所求
int p = Math.min(k/2, len1);
int q = k - p;
if (nums1[start1 + p - 1] < nums2[start2 + q - 1]) {
return recur(nums1, nums2, start1 + p, start2, len1 - p, len2, k - p);
} else if (nums1[start1 + p - 1] > nums2[start2 + q - 1]) {
return recur(nums1, nums2, start1, start2 + q, len1, len2 - q, k - q);
} else {
// 返回下一个位置较小的
return nums1[start1 + p - 1];
}
}
}