【408算法】2011 两个升序序列的中位数

165 阅读2分钟

题目

一个长度为 L(L>=1) 的升序序列 S, 其中处于 [L/2] 位置的数称为 S 的中位数,

比如升序 S1=(11,13,15,17,19), 则 S1 的中位数是 15,

两个序列的中位数是含他们所有元素序列的中位数.

例如,若 S2=(2,4,6,8,20), 则 S1 和 S2 的中位数是 11(2,4,6,8,11,13,15,17,19,20).

现在有两个等长升序序列A和B, 试设计一个在时间和空间两方面都尽可能高效的算法, 找出两个序列 A 和 B的中位数.

要求:

1)给出算法的基本设计思想

2)根据思想, 采用 C , C++ 或 Java 语言描述算法, 关键之处给出注释

3)说明你所设计的算法时间复杂度和空间复杂度

暴力解

思路

将两个数组放入新的数组用快速排序,输出排序后数组中第n个元素

时间复杂度:O(nlogn)

空间复杂度:O(n)

算法

#include <cstdio>
#include <cstdlib>
#include <algorithm>

//快排
void quick_sort(int arr[], int left, int right) {
    if(left >= right) return;

    // 随机交换
    int datum, i = left, j = right;
    std::swap(arr[left], arr[rand()%(right - left + 1) + left]); 
    datum = arr[left];
    while(i < j) {
        while(i < j && arr[j] > datum) j--;
        while(i < j && arr[i] <= datum) i++;
        if(i < j) std::swap(arr[i], arr[j]);
    }
    std::swap(arr[left], arr[i]);
    quick_sort(arr, left, i-1);
    quick_sort(arr, i+1, right);
}

int find_mid(int arr_a[], int arr_b[], int lenght) {
    // 合并数组
    int* arr_merage = (int*) malloc(sizeof (int) * 2 * lenght);
    for (int i =0; i<lenght; i++) {
        arr_merage[i] = arr_a[i];
        arr_merage[lenght+i] = arr_b[i];
    }
    // 快排 
    quick_sort(arr_merage, 0, 2*lenght -1);
    
    // 输出中位数
    return arr_merage[lenght-1];
}

//====================以下为测试======================

int main() {
    int arr_a[] = {11, 13, 22, 15, 17, 19};
    int arr_b[] = {2, 4, 6, 8, 20, 21};
    int lenght = sizeof(arr_a)/sizeof(arr_a[0]); // 数组成员的个数
    int mid = find_mid(arr_a, arr_b, lenght);

    printf("\n%d", mid);
    return 0;
}