https://leetcode.com/problems/median-of-two-sorted-arrays/
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
题目原文在这里。
这里,关注算法的递归写法,保持了num1和nums2的长短关系。
class Solution {
public:
// n1 is always the shorter one
// here k=1 means the first one
int findKth(vector<int>& nums1, int st1, int ed1, vector<int>& nums2, int st2, int ed2, int k) {
if(ed1-st1 > ed2-st2) {
return findKth(nums2, st2, ed2, nums1, st1, ed1, k);
}
if(ed1 == st1) {
return nums2[st2+k-1];
}
if(1 == k) {
return min(nums1[st1], nums2[st2]);
}
int movea = min(k>>1, ed1-st1), moveb = k-movea;
int i = st1+movea-1, j = st2+moveb-1;
if(nums1[i] == nums2[j]) {
return nums1[i];
} else if(nums1[i] < nums2[j]){
return findKth(nums1, st1+movea, ed1, nums2, st2, ed2, k-movea);
} else {
return findKth(nums1, st1, ed1, nums2, st2+moveb, ed2, k-moveb);
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if(!m && !n) {
return 0;
}
int l = m+n;
if(l&1) {
return findKth(nums1, 0, m, nums2, 0, n, (l+1)>>1);
} else {
return (findKth(nums1, 0, m, nums2, 0, n, l>>1) + findKth(nums1, 0, m, nums2, 0, n, (l>>1)+1))/2.0;
}
}
};
循环实现:
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(null == nums1 || null == nums2) {
return findKth(nums1, nums2);
}
int lena = nums1.length, sta = 0;
int lenb = nums2.length, stb = 0;
// num is the number of first midian and numbers before it
// for [1,2,3,4], num = 2;
int len = lena + lenb, num = (len+1)>>1;
if(0 == len) {
return 0.0;
}
while(sta < lena && stb < lenb) {
int n = min(num>>1, lena-sta, lenb-stb);
if(0 == n) {
return pick(nums1, sta, nums2, stb, num, 1 == (len&0x1));
}
int va = nums1[sta+n-1], vb = nums2[stb+n-1];
if(va == vb) {
return pick(nums1, sta, nums2, stb, n, num, 1 == (len&0x1));
} else if(va <= vb){
sta = sta + n;
} else {
stb = stb + n;
}
num -= n;
}
if(sta < lena) {
return pick(nums1, sta, num, 1 == (len&0x1));
} else {
return pick(nums2, stb, num, 1 == (len&0x1));
}
}
// when n==0
private double pick(int[] nums1, int sta, int[] nums2, int stb, int num, boolean odd) {
if(odd) {
return Math.min(nums1[sta], nums2[stb]);
}
return pick(nums1, sta, nums2, stb, num);
}
// pick when need two number
private double pick(int[] nums1, int ia, int[] nums2, int ib, int num) {
if(0 < num) {
return pickCheckNext(nums1, ia, nums2, ib);
}
return (nums1[ia] + nums2[ib])/2.0;
}
private double pickCheckNext(int[] nums1, int ia, int[] nums2, int ib) {
int a=nums1[ia], b=nums2[ib];
if(ia+1<nums1.length && b>nums1[ia+1]) {
b = nums1[ia+1];
}
if(ib+1<nums2.length && a>nums2[ib+1]) {
a = nums2[ib+1];
}
return (a+b)/2.0;
}
// when there are two number that are the same
private double pick(int[] nums1, int sta, int[] nums2, int stb, int n, int num, boolean odd) {
if(odd) {
if(n+n == num) {
return nums1[sta+n-1];
}
return Math.min(nums1[sta+n], nums2[stb+n]);
} else {
if(n+n == num) {
return (nums1[sta+n-1]+Math.min(nums1[sta+n], nums2[stb+n]))/2.0;
} else {
return pick(nums1, sta+n, nums2, stb+n, num);
}
}
}
private double pick(int[] nums, int st, int num, boolean odd) {
if(odd) {
return nums[st+num-1];
}
return (nums[st+num-1] + nums[st+num])/2.0;
}
private double findKth(int[] a, int[] b) {
if(null == a && null == b) {
return 0;
}
if(null == a) {
return findKth(b);
} else {
return findKth(a);
}
}
private double findKth(int[] a) {
int len = a.length;
if(1 == len) {
return a[0];
}
return (a[len>>1]+a[(len-1)>>1])/2.0;
}
private int min(int a, int b, int c) {
if(a < b) {
if(a < c) {
return a;
}
} else {
if(b < c) {
return b;
}
}
return c;
}
}
高效解决两个已排序数组的中位数问题

被折叠的 条评论
为什么被折叠?



