2-6 两个有序序列的中位数 (20分)-HBU DS

    科技2025-01-08  16

    2-6 两个有序序列的中位数 (20分)-HBU DS

    已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,A**N−1的中位数指A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0为第1个数)。

    输入格式:

    输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

    输出格式:

    在一行中输出两个输入序列的并集序列的中位数。

    输入样例1:

    5 1 3 5 7 9 2 3 4 5 6

    输出样例1:

    4

    输入样例2:

    6 -100 -10 1 1 1 1 -50 0 2 3 4 5

    输出样例2:

    1

    思路:

    这个题的我的思路就是:先把S1 S2存起来,然后俩指针分别指向他们的首元素,那个指针指向的元素小,那个指针就指向下一个节点,并且计数器加1。计数器从0开始,现在找的中位数是第(N+1)/2个数,一次循环后,cnt是1,num存的是第一个数。现在一共有2*N个元素,就是要找第(2 * N+1)/2个数,即当cnt是(2 *N+1)/2时。所以循环条件是cnt < (2 *N+1) / 2 ,当出循环时,cnt刚好等于(2 *N+1)/2。

    代码

    #include <iostream> using namespace std; typedef struct Node *List; struct Node { int data; List next; }; List Read(int n); int main() { int N; cin >> N; List L1 = Read(N); List L2 = Read(N); List pa = L1->next, pb = L2->next; int cnt = 0; int num; while (pa && pb && cnt < (2*N+1) / 2) { if (pa->data <= pb->data) { num = pa->data; cnt++; pa = pa->next; } else { num = pb->data; cnt++; pb = pb->next; } } printf("%d", num); } List Read(int n) { List L = (List)malloc(sizeof(Node)), temp, s; L->next = NULL; temp = L; while (n--) { s = (List)malloc(sizeof(Node)); cin >> s->data; s->next = NULL; temp->next = s; temp = s; } return L; }
    Processed: 0.010, SQL: 8