Give two sorted array, find the k-th smallest element of uni

Source: Internet
Author: User

Give you two sorted array, find the k-th smallest elements of union of A and B, you can assume that there are no duplicate elements. the size of A is m, and size of B is n, both them are in acsending order. at first, we can use brute-force, malloc a new array of size m + n, and merge A and B into this new array, then we can get the k-th smallest element, or k-th smallest elements. time complexity is O (m + n), and the space complexity is O (m + n); A better way, using two pointers: I, and j, I proints head of, j points to head of B, at the same time make a new malloc of array of size k. then we compare A [I] and B [j], we get the minimum of them and increase pointer of the minimum one in order to get next index of the array its belonged. time complexity is O (k), and space complexity is O (k ). her E is the codes: [cpp] # include <iostream> # include <cassert> using namespace std; int * get_k_th_minimum (int * a, int len_a, int * B, int len_ B, int k) {int p = 0; int I = 0; int j = 0; int * c = (int *) malloc (sizeof (int) * k ); if (a = NULL | B = NULL | k> (len_a + len_ B) {return NULL ;} while (p <k & I <len_a & j <len_ B) {if (a [I] <B [j]) {c [p ++] = a [I]; I ++;} else {c [p ++] = B [j]; j ++ ;}} Return c;} void main () {int a [] = {1, 3, 5, 7, 9}; int B [] = {2, 4, 6, 8, 10}; int len_a = sizeof (a)/sizeof (int); int len_ B = sizeof (B)/sizeof (int); int k = 5; int * p = get_k_th_minimum (a, len_a, B, len_ B, k); int I = 0; if (p) {for (I = 0; I <k; I ++) {cout <p [I] <"" ;}cout <endl ;}getchar () ;}then a more better way, it takes O (lgm + lgn) time to get the k-th minimum elements, not All the number of k elements. then we will take O (k) time to get these elements from A and B. and space complexity is O (1 ). we try to approach this tricky problem by comparing middle elements of A and B, which we identify as Ai and Bj. if Ai is between Bj-1 and Bj, it shows that Ai is the I + j + 1 (index is from zero) smallest element, including Bj-1 there are j elements in B smaller than Ai, and ther E are I elements smaller than Ai. so Ai is the I + j + 1 smallest element in union of A and B. therefore, if we choose I and j such that I + j + 1 = k. then we find the k-th smallest element. this is an important invariant that we must maintain for the correctness of this algorithm. summerizing abve is: Maintaining the invariant I + j = k-1 if Bj-1 <Ai <Bj, then Ai must be the k-th smallest. if I-1 <Bj <Ai, then Bj must be the k-th smallest. if one of the conditions above is satisfied, then we get k-th smallest element. if both are not, we have to consider what we shoshould do next? First, if we assume this condition: Bj-1 <Ai <Bj is not satisfied, and we can get two reasons of this failure: one is Ai> Bj, and the other is Ai <Bj-1, then we also assume that this condition: Ai-1 <Bj <Ai is also not satisfied. then we can clearly get that is: Ai <Bj-1 makes Ai or Bj is not the k-th smallest element. we make a summerization than when Ai <Bj, then Ai <Bj-1, on the other Hand, if Bj <Ai, then Bj <Ai-1.Using the above relationship, we can get Ai and its lower portion cocould never be the k-th smallest element. let me make a explanation, if we assume that Bj-2 <Ai <Bj-1, then Ai will be the I + 1 + J-1 smallest elements, I. e (k-1) th, and this is the best situation and how about Ai <Bj-2, or Ai <Bj-3, and how about Ai's lower portion? So we discard Ai and its lower portion and why not Bj and its lower portion, think about that is there any possibility that Ai + 1 <Bj-1 <Ai + 2, if this can be true and then Bj-1 is the k-th smallest element. and to Bj's uper portion we also discard, why? Because Ai <Bj + 1, and there are total j + 1 + I + 1 elements smaller than Bj + 1. so we discard it. on the other hand, the case for Ai> Bj is just the other way around. easy. below is the code and I have inserted lots of assertion (highly recommended programming style by the way) to help you understand the code. note that the below code is an example of tail recursion, so you cocould technically co Nvert it to an iterative method in a straightforward manner. however, I wowould leave it as it is, since this is how I derive the solution and it seemed more natural to be expressed in a recursive manner. another side note is regarding the choices of I and j. the below code wocould subdivide both arrays using its array sizes as weights. the reason is it might be able to guess the k-th element quicker (As long as the and B is not differed in an extreme way; ie, all elements in A are smaller than B ). if you are wondering, yes, you cocould choosei to be A's middle. in theory, you cocould choose any values for I and j as long as the invariant I + j = k-1 is satisfied. here is the code: [cpp] # include <iostream> # include <cassert> using namespace std; int flag = 0; int get_k_th_minimum (int * a, int m, int * B, int n, int k) {assert (m> = 0); assert (n> = 0); assert (k <= (m + n )); int I = (int) (double) m/(m + n) * (k + 1); int j = (k-1)-I; assert (I> = 0); assert (j> = 0); assert (I <= m); assert (j <= n ); int Ai_1 = (I = 0 )? INT_MIN: a [I-1]); int Bj_1 = (j = 0 )? INT_MIN: B [J-1]); int Ai = (I = m )? INT_MAX: a [I]); int Bj = (j = n )? INT_MAX: B [j]); if (Bj_1 <Ai & Ai <Bj) {flag = 0; return Ai;} else if (Ai_1 <Bj & Bj <Ai) {flag = 1; return Bj;} assert (Ai> Bj & Ai_1> Bj) | (Ai <Bj & Ai <Bj_1 )); if (Ai <Bj) {get_k_th_minimum (a + I + 1, m-I-1, B, j, k-I-1);} else {get_k_th_minimum (, i, B + j + 1, n-j-1, k-j-1) ;}} void main () {int I = 0; int j = 0; int a [] = {1, 3, 5, 7, 9}; int B [] = {2, 4, 6, 8, 10}; int len_a = sizeof (a)/sizeof (int); int len_ B = sizeof (B)/sizeof (int); int k = 6; int result = get_k_th_minimum (a, len_a-1, B, len_ B-1, k); if (flag = 0) {while (a [I]! = Result) {cout <a [I] <""; I ++;} for (j = 0; j <k-I-1; j ++) {cout <B [j] <"" ;}www.2cto.com cout <result <endl ;}else {while (B [I]! = Result) {cout <B [I] <""; I ++;} for (j = 0; j <k-I-1; j ++) {cout <a [j] <";}cout <result <endl ;}getchar ();}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.