int find_kth(vector<int>::iterator nums1, int m, vector<int>::iterator nums2, int n, int k){ //always let nums1's size smaller or equal to nums2 if(m>n){ return find_kth(nums2,n,nums1,m,k); } if(m==0){ return *(nums2+k-1); } if(k==1){ return min(*nums1,*nums2); } //divide k into tow parts int mid1=min(k/2,m),mid2=k-mid1; vector<int>::iterator iter; if(*(nums1+mid1-1)<*(nums2+mid2-1)){ return find_kth(nums1+mid1,m-mid1,nums2,n,k-mid1); }else if (*(nums1+mid1-1)>*(nums2+mid2-1)){ return find_kth(nums1,m,nums2+mid2,n-mid2,k-mid2); }else{ return nums1[mid1-1]; } }
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { int total = nums1Size + nums2Size; if(total & 0x1) return find_kth(nums1,nums1Size,nums2,nums2Size,total/2+1); else return (find_kth(nums1,nums1Size,nums2,nums2Size,total/2)+find_kth(nums1,nums1Size,nums2,nums2Size,total/2+1))/2.0; }
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { int all = nums1Size + nums2Size; int k = all / 2 + 1; double ans = find_kth(nums1, nums1Size, nums2, nums2Size, k); if(all % 2) return ans; return (ans + find_kth(nums1, nums1Size, nums2, nums2Size, k-1)) / 2; }
double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) { const int total = nums1.size() + nums2.size(); if (total % 2)//奇数 return find_kth(nums1, 0, nums2, 0, total / 2 + 1); else//偶数 return (find_kth(nums1, 0, nums2, 0, total / 2) + find_kth(nums1, 0, nums2, 0, total / 2 + 1)) / 2; }
double findMedianSortedArrays(int A[], int m, int B[], int n) { int total = m + n; if(total & 0x1) { //奇数个元素,取中间元素 return find_kth(A, m, B, n, total/2 + 1); } else { //偶数个元素,取中间两个元素的平均 return (find_kth(A, m, B, n, total/2) + find_kth(A, m, B, n, total/2 + 1))/2; } }
// 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)). // The median: https://en.wikipedia.org/wiki/Median double Array::findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { const int m = nums1.size(), n = nums2.size(); const int total = m + n; if (total & 1) return find_kth(nums1.begin(), m, nums2.begin(), n, total / 2 + 1); else return (find_kth(nums1.begin(), m, nums2.begin(), n, total / 2) + find_kth(nums1.begin(), m, nums2.begin(), n, total / 2 + 1)) / 2.0; }
int main() { List l; for (int i = 0; i < 10; i++) l.add(i); assert(find_kth(l, 0) == 9); assert(find_kth(l, 1) == 8); assert(find_kth(l, 9) == 0); }
TreapNode * find_kth(TreapNode*x, int k) { if (x == NULL) return NULL; int lsz = LSZ(*x); if (k <= lsz) { return find_kth(x->ch[0], k); } else if (k == lsz + 1) { return x; } else { return find_kth(x->ch[1], k - lsz - 1); } }
/* Divide and Conquer inspired by find k-th number in sorted array. The complexity is of course O(log(M+N)). Similiar with the following answer except without slicing. https://discuss.leetcode.com/topic/6947/intuitive-python-o-log-m-n-solution-by-kth-smallest-in-the-two-sorted-arrays-252ms */ double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int len1 = nums1.size(); int len2 = nums2.size(); int len = len1 + len2; if(len & 0x1 == 1){ return find_kth(nums1, 0, len1, nums2, 0, len2, (len+1)/2); } else{ return (find_kth(nums1, 0, len1, nums2, 0, len2, (len)/2) + find_kth(nums1, 0, len1, nums2, 0, len2, (len)/2+1)) / 2.0; } }
void find_kth(vector<int>& a, int left, int right, int k) { int pivot = a[right]; int pos = left; for (int i=left;i<right;++i) if (a[i] < a[right]) swap(a[i], a[pos++]); swap(a[pos],a[right]); if (k == pos) return; if (pos < k) find_kth(a, pos+1, right, k); if (pos > k) find_kth(a, left, pos-1, k); }
int find_kth(int *A, int m, int *B, int n, int k){//查找第k小的值 if(m>n) return find_kth(B,n,A,m,k); //保证m<=n if(m==0) return B[k-1]; //终止条件1:其中一个长度为0; if(k==1) return min(A[0],B[0]);//终止条件2:查找最小值; int ia=min(k/2,m),ib=k-ia; if(A[ia-1]<B[ib-1]) //若A第ia个元素小,抛弃左侧元素 return find_kth(A+ia,m-ia,B,n,k-ia); else if(A[ia-1]>B[ib-1]) //若B第ib个元素小,抛弃左侧元素 return find_kth(A,m,B+ib,n-ib,k-ib); else return A[ia-1]; //终止条件3:找到了目标值; }
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m=nums1.size(); int n=nums2.size(); int total = m+n; if(total & 0x1){ return find_kth(nums1.begin(),m,nums2.begin(),n,total/2+1); }else{ return (find_kth(nums1.begin(),m,nums2.begin(),n,total/2) +find_kth(nums1.begin(),m,nums2.begin(),n,total/2+1))/2.0; } }
int Array::find_kth(vector<int>::const_iterator a, int m, vector<int>::const_iterator b, int n, int k) { if (m > n) return find_kth(b, n, a, m, k); if (m == 0) return *(b + k - 1); if (k == 1) return min(*a, *b); // divide k into two parts int ia = min(k / 2, m), ib = k - ia; if (*(a + ia - 1) < *(b + ib - 1)) return find_kth(a + ia, m - ia, b, n, k - ia); else if (*(a + ia - 1) > *(b + ib - 1)) return find_kth(a, m, b + ib, n - ib, k - ib); else return a[ia - 1]; }
int find_kth(int a[],int b[],int size_a,int size_b,int k) { if(size_a > size_b) return find_kth(b,a,size_b,size_a,k); // make the smaller array as A if(size_a == 0 && size_b > 0) return b[k-1]; // if one array is empty simply return kth index value if(k==1) return (a[0]<=b[0])? a[0]:b[0]; // if k is the smallest element return smallest value int i = (size_a <= k/2)? size_a: k/2; int j = (size_b <= k/2)? size_b: k/2; //find the k/2 index in the array or the max length if less if(a[i-1] < b[j-1]) return find_kth(a+i,b,(size_a-i),j,(k-i)); else return find_kth(a,b+j,i,(size_b-j),(k-j)); //discard the side of both the arrays in which k cannot be present }
double find_kth(int * a, int n1, int * b, int n2, int k){ if(n1 == 0) return b[k-1]; if(n2 == 0) return a[k-1]; if(k == 1) return a[0]<b[0]?a[0]:b[0]; int amid = n1 / 2; int bmid = n2 / 2; if(a[amid] <= b[bmid]){ if(amid + bmid + 1 >= k) return find_kth(a, n1, b, bmid, k); return find_kth(a+amid+1, n1-amid-1, b, n2, k-amid-1); } return find_kth(b, n2, a, n1, k); }
void main(void) { int a[100]; int b[100]; int size_a = 0; int size_b = 0; while(1) { int var = 0; printf("Enter Array A elements (end with -1)\n"); scanf("%d",&var); if(var == -1) break; a[size_a++] = var; } while(1) { int var = 0; printf("Enter Array B elements (end with -1)\n"); scanf("%d",&var); if(var == -1) break; b[size_b++] = var; } printf("ENTER THE VALUE FOR K\n"); int k; scanf("%d",&k); int answer = find_kth(a,b,size_a,size_b,k); printf("The %dth smallest element is %d\n",k,answer); }
double find_kth(int A[], int m, int B[], int n, int k) { if(m > n) return find_kth(B, n, A, m, k); //假定m小于等于n,这样处理更方便 //按照前面的分析,下面是两个终止的情况 if(m == 0) return B[k-1]; if(k == 1) return min(A[0], B[0]); //pa取k/2,如果m比k/2小,pa取m int pa = min(k/2, m), pb = k - pa; //二分法的变形 if(A[pa-1] < B[pb-1]) { //这种情况可以放心去掉A的pa个元素(k/2或者全部) return find_kth(A+pa, m-pa, B, n, k-pa); } else if(A[pa-1] > B[pb-1]) { //这种情况可以放心去掉B的pb个元素(k/2或者更多) return find_kth(A, m, B+pb, n-pb, k-pb); } else { return A[pa-1]; } }
void left(int ax,int ay) { int p,i,f; for(i=ax-r;i<=ax+r;i++) { plus(old[i][ay-r-1],-1); plus(old[i][ay+r],1); } p=find_kth(k); neww[ax][ay]=p; }
double find_kth(std::vector<int>& A, int m, std::vector<int>& B, int n, int k) { if (A.size() > B.size())//默认A数组要小 return find_kth(B, n, A, m, k); if (m >= A.size())//A数组为空,说明第K小的元素在数组B中 return B[n + k - 1]; if (n >= B.size()) return A[m + k - 1]; if (k == 1)//找第1小的元素 return std::min(A[m], B[n]); int pa = std::min(k / 2, int(A.size() - m)), pb = k - pa;//注意pb的算法,k-pa可以使pa和pb加起来等于k if (A[m + pa - 1] < B[n + pb - 1])//如果小于,表示数组A的pa-1位置以下的元素都不是,可以删除 return find_kth(A, m + pa, B, n, k - pa); else if (A[m + pa - 1] > B[n + pb - 1])//如果大于,表示数组B的pb - 1下标以下的元素都不是第k小的元素,可以删除 return find_kth(A, m, B, n + pb, k - pb); else//相等,表示这就是第k小的元素,因为pa+pb等于k return A[m + pa - 1]; }
void up(int ax,int ay) { int p,i,f; for(f=ay-r;f<=ay+r;f++) { plus(old[ax-r-1][f],-1); plus(old[ax+r][f],1); } p=find_kth(k); neww[ax][ay]=p; }
int find_kth(vector<int>& list1, int begin1, int end1, vector<int>& list2, int begin2, int end2, int k){ /* Find the kth number in two sorted list: list1 , list2 Binary search as followers: Firstly cut list1 and list2 into two parts by t1 and t2, respectively. 1. lis1_left ... list1[t1-th] ... list1_right, 2. lis2_left ... list2[t2-th] ... list2_right Then compare value of list1[t1-th] and list2[t2-th] in list2. Three situations about the relation between list1[t1-th] and list2[t2-th]: 1. < Equal the (k-t1)th number in list1_right and list_2 left. 2. > Equal the (k-t2)th number in list1_left and list_2 right. 3. == Find the k-th number. */ int len1 = end1 - begin1; int len2 = end2 - begin2; if(len1 > len2){ return find_kth(list2, begin2, end2, list1, begin1, end1, k); } if(len1 == 0){ return list2[begin2+k-1]; } if(k==1){ return min(list1[begin1], list2[begin2]); } int t1 = min(k/2, len1); int t2 = k - t1; if(list1[begin1+t1-1] < list2[begin2+t2-1]){ return find_kth(list1, begin1+t1, end1, list2, begin2, begin2+t2, k-t1); } else if(list1[begin1+t1-1] > list2[begin2+t2-1]){ return find_kth(list1, begin1, begin1+t1, list2, begin2+t2, end2, k-t2); } else{ return list1[begin1+t1-1]; } }
void fun() { int ax,ay; int i,f,p; for(i=1;i<=2*r+1;i++) { for(f=1;f<=2*r+1;f++) { plus(old[i][f],1); } } p=find_kth(k); neww[r+1][r+1]=p; for(ax=r+1;ax<=n-r;ax++) { if(1 == 1&(ax-r)) { for(ay=r+1;ay<=n-r;ay++) { if(ax==ay&&ax==r+1) { continue; } if(ay == r+1) { up(ax,ay); } else { left(ax,ay); } } } else { for(ay=n-r;ay>=r+1;ay--) { if(ay == n-r) { up(ax,ay); } else { right(ax,ay); } } } } }
void solve() { value[++total] = -99999999; count[total] = 1; root = total; int N; std::scanf("%d", &N); for(int i = 0; i != N; ++i) { int opt, x; std::scanf("%d %d", &opt, &x); switch(opt) { case 1: insert(x); break; case 2: remove(x); break; case 3: std::printf("%d\n", find_rank(x) - 1); break; case 4: std::printf("%d\n", find_kth(x + 1)); break; case 5: opt = find_prev(x); splay(opt); std::printf("%d\n", value[opt]); break; case 6: opt = find_next(x); splay(opt); std::printf("%d\n", value[opt]); break; } } }
void wiggleSort(vector<int>& a) { if (a.size()<2) return ; // deal with odd length int len = a.size(); if (len % 2 == 1) { int min_pos = 0; for (int i=1;i<len;++i) if (a[i] < a[min_pos]) min_pos = i; swap(a[min_pos], a[--len]); } int k = len/2 - 1; find_kth(a, 0, len-1, k); // a[k] will be the kth number in a // a[0]..a[k-1] are all leq a[k] // a[k+1]..a[len-1] are all geq a[k] // cout << k << endl; // for (int i=0;i<a.size();++i) // cout << a[i] << " "; // cout << endl; int special = a[k]; // cout << "special: " << special << endl; for (int i=1;i<=k;i+=2) swap(a[i],a[k+1+i]); for (int i=1;i<len;i+=2) if (a[i-1] > a[i]) swap(a[i-1],a[i]); // cout << "Make paris" << endl; // for (int i=0;i<a.size();++i) // cout << a[i] << " "; // cout << endl; int p1 = 0, p2 = 0; for (;p2<len;p2+=2) if (a[p2] == a[p2+1]) { while (p1<len && (a[p1]==special ||a[p1+1] == special)) p1+=2; swap(a[p1],a[p2]); } // cout << "Solve conflicts within a pair" << endl; // for (int i=0;i<a.size();++i) // cout << a[i] << " "; // cout << endl; p1 = 0; for (p2=0;p2<len;p2+=2) if (a[p2] == special) { while (p1<len && a[p1] == special) p1 += 2; if (p1 >= p2) continue; swap(a[p1],a[p2]); swap(a[p1+1],a[p2+1]); } // cout << "Solve conflicts between pairs" << endl; // for (int i=0;i<a.size();++i) // cout << a[i] << " "; // cout << endl; }
int find_kth(int k) { if (k < 1 || k > size()) return -1; TreapNode *x = find_kth(root, k); if (x) return x->val + delta; return -1; }