double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { int m = nums1Size + nums2Size; if(m==0) return 0; if(m%2) { return findkth(nums1, nums1Size, nums2, nums2Size, m/2+1); } return (findkth(nums1, nums1Size, nums2, nums2Size, m/2) + findkth(nums1, nums1Size, nums2, nums2Size, m/2+1)) / 2.0; }
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if((nums1Size+nums2Size)%2){ return findkth(nums1,nums1Size,nums2,nums2Size,(nums1Size+nums2Size)/2+1)*1.0; }else{ return (findkth(nums1,nums1Size,nums2,nums2Size,(nums1Size+nums2Size)/2) +findkth(nums1,nums1Size,nums2,nums2Size,(nums1Size+nums2Size)/2+1))/2.0; } }
double findMedianSortedArrays(int A[], int m, int B[], int n) { // Start typing your C/C++ solution below // DO NOT write int main() function int len = m+n; if (len%2==1){ return findkth(A,m,B,n,len/2+1); } else{ return (findkth(A,m,B,n,len/2+1) + findkth(A,m,B,n,len/2))/2; } }
double findMedianSortedArrays(vector<int> A, vector<int> B) { // write your code here int total_size = A.size() + B.size(); // if the total size is odd if (total_size & 0x1) { return findkth(A, B, total_size / 2 + 1, 0, 0); } else { return (findkth(A, B, total_size / 2, 0, 0) + findkth(A, B, total_size / 2 + 1, 0, 0) ) / 2; } }
double findkth(double array[],int low,int high, int k){ double kth; if(low == high) kth = array[low]; else{ double pivot = array[low]; int splitpoint = partition(array,low,high); if(k-1 == splitpoint) kth = pivot; else if(k-1<splitpoint) kth = findkth(array,low,splitpoint-1,k); else if(k-1>splitpoint) kth = findkth(array,splitpoint+1,high,k); } return kth; }
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size(); int n = nums2.size(); int k = (m + n + 1) /2; double med = (double) findkth(nums1, nums2, 0, m , 0, n , k); cout<<med<<endl; if((m + n) % 2 == 0){ double med2 = (double) findkth(nums1, nums2, 0, m , 0, n , k+1); cout << med2 <<endl; med = (med + med2)/2; } return med; }
int findkth(int* v1, int sz1, int* v2, int sz2, int k){ if(sz1 < sz2) return findkth(v2, sz2, v1, sz1, k); // assert(sz1 >= sz2); if(sz2 == 0) return v1[k-1]; if(k == 1) return min(v1[0], v2[0]); int j = min(sz2, k/2); int i = k-j; if(v1[i-1] < v2[j-1]) return findkth(v1+i, sz1-i, v2, sz2, k-i); return findkth(v1, sz1, v2+j, sz2-j, k-j); }
double findkth(int a[], int m, int b[], int n, int k) { if (m > n) return findkth(b, n, a, m, k); if (m == 0) return b[k-1]; if (k == 1) return MIN(a[0], b[0]); int pa = MIN(k/2, m), pb = k - pa; if (a[pa-1] < b[pb-1]) return findkth(a+pa, m-pa, b, n, k - pa); else if (a[pa-1]>b[pb-1]) findkth(a, m, b+pb, n-pb, k-pb); else { printf("equal %d\n", a[pa-1]); return a[pa-1]; } /* same as if (a[pa-1] < b[pb-1]) return findkth(a+pa, m-pa, b, n, k - pa); else return findkth(a, m, b+pb, n-pb, k-pb); */ }
double findkth(int A[], int m, int B[], int n, int k) { // make sure A is no bigger than B if(m>n) return findkth(B,n,A,m,k); // if A empty, find in B if(m==0) return B[k-1]; // if to find the smallest, find between A[0] and B[0] if(k==1) return min(A[0],B[0]); // both A and B non-empty and to find at least the second smallest int apart = min(k/2,m); int bpart = k-apart; if(A[apart-1] < B[bpart-1]) return findkth(A+apart,m-apart,B,n,k-apart); else return findkth(A,m,B+bpart,n-bpart,k-bpart); }
// find the kth min in sorted array A, B; k is the order. // each time when one middle value less than the other one, skip all these till mid + 1 double findkth(vector<int> &A, vector<int> &B, int k, int index_a, int index_b) { if (A.size() - index_a > B.size() - index_b) return findkth(B, A, k, index_b, index_a); if (A.size() - index_a == 0) return B[k - 1]; if (k == 1) { return min(A[index_a], B[index_b]); } int mid_a = min((int)A.size() - index_a, k/2); int mid_b = k - mid_a; if (A[index_a + mid_a - 1] < B[index_b + mid_b - 1]) { return findkth(A, B, k - mid_a, index_a + mid_a, index_b); } else if (A[index_a + mid_a - 1] > B[index_b + mid_b - 1]) { return findkth(A, B, k - mid_b, index_a, index_b + mid_b); } else return A[mid_a - 1]; }
int main(int argc, char* argv[]) { //int a[]={3,4,5,6,7}; //int b[]={1,2,3}; int a[]= {100001}; int b[]= {100000}; int m=1,n=1; int median=(m+n)/2; printf("median %d\n", median); if((m+n)%2) { int r= findkth(a,m,b,n,median+1); printf("odd %d\n", r); } else { int p= findkth(a,m,b,n,median); int q= findkth(a,m,b,n,median+1); printf("even %d %d %f\n", p,q,(p+q)/2.0); } return 1; }
int findkth(vector<int> & nums1, vector<int>& nums2, int begin1, int size1, int begin2, int size2, int k){ cout << size1 << " "<< size2<<endl; if(size1 > size2){ return findkth(nums2, nums1, begin2, size2, begin1, size1, k); } if(size1 == 0) // if its the end of the nums1 then we find the kth smallest num in nums2 //cout<<nums2[0]<<endl; return nums2[k-1]; if(k == 1) return min(nums1[begin1], nums2[begin2]); int k1 = min(k/2, size1); // k1 n -k1 int k2 = k - k1; // k - k1 m - ( k - k1) // left k right m + n - k if(nums1[begin1 + k1 - 1] < nums2[begin2 + k2 - 1]) // then the kth smallest is in the right sid return findkth(nums1, nums2, begin1 + k1, size1 - k1, begin2, size2, k - k1); return findkth(nums1, nums2, begin1, size1, begin2 + k2, size2 - k2, k - k2); }
int findkth(int* a,int aSize,int*b,int bSize,int k) { int aPos,bPos; if(aSize>bSize){ return findkth(b,bSize,a,aSize,k); } if(aSize==0){ return b[k-1]; } if(k==1){ return a[0]<b[0] ? a[0] : b[0]; } aPos = k/2<aSize ? k/2 : aSize; bPos = k-aPos; if(a[aPos-1]==b[bPos-1]){ return a[aPos-1]; }else if(a[aPos-1]<b[bPos-1]){ return findkth(a+aPos,aSize-aPos,b,bSize,k-aPos); }else{ return findkth(a,aSize,b+bPos,bSize-bPos,k-bPos); } }