关闭

[LeetCode]Median of Two Sorted Arrays

301人阅读 评论(0) 收藏 举报
分类:

这里写图片描述

题目的要求实际上是log(m+n)
实际提交时(m+n)log(m+n)也是对的
c++实现时,两句话就可以了,两个vector放一起
sort一些即可
锻炼一下c的能力,写了下快排

//交换两个元素
void swap(int *a, int *b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int median3(int *v, int left, int right){
    int median = (left+right)/2;
    //先将最小的放在left
    if(v[median]<v[left])
        swap(v+median, v+left);
    if(v[right]<v[left])
        swap(v+right,v+left);
    //中间的数放在median
    if(v[median]>v[right])
        swap(v+median, v+right);
    swap(v+median, v+right-1);
    return v[right-1];
}
void InsertSort(int *v, int N){
    int tmp;int i,j;
    for(i = 1; i != N; ++i){
        tmp = v[i];
        for(j = i; j!=0&&v[j-1]>tmp; --j)
            v[j]=v[j-1];
        v[j] =tmp;
    }
}
void QuickSort(int *v, int left, int right){
    if((right-left)>16){
    int i = left, j = right-1;
    int pivot = median3(v, left, right);
    for(;;){
        while(v[++i]<pivot){}
        while(v[--j]>pivot){}
        if(i<j)
            swap(v+i,v+j);
        else
            break;
    }
    swap(v+right-1, v+i);
    QuickSort(v,left,i-1);
    QuickSort(v,i+1,right);
    }
    else
        InsertSort(v+left, right-left+1);

}
void Quick_Sort(int *v, int N){
    QuickSort(v,0,N-1);
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
        int *v = (int*)malloc(sizeof(int)*(nums1Size+nums2Size));
        for(int i = 0; i!= nums1Size; ++i)
            v[i] = nums1[i];
        for(int j = 0; j!= nums2Size; ++j)
            v[nums1Size+j]=nums2[j];
        int v_size = nums1Size+nums2Size;
        Quick_Sort(v,v_size);
        if(v_size%2)
            return v[(v_size-1)/2];
        else
            return (v[v_size/2]+v[v_size/2-1])/2.0;
}

补充
o(m+n)寻找kth

#include<iostream>

using namespace std;

int findkth(int *a,int m, int *b,int n,int k){
    if(m==0)
        return b[k-1];
    if(n==0)
        return a[k-1];
    if(k==1)
        return a[0]<b[0]?a[0]:b[0];
    int idx = 1;    //现在指向第k大的数
    int i = 0;
    int j = 0;
    while(idx!=k){
        while(a[i]<b[j]){if(idx==k) return a[i];++i;++idx;}
        while(a[i]>=b[j]){if(idx==k) return b[j];++j; ++idx;}
    }
}

int main(){
    int a[4]={1,2,3,6};
    int b[2]={5,7};
    cout <<findkth(a,4,b,2,5)<<endl;
    return 0;

}

一个很好的方法
最后从medianof two sorted arrays中看到了一种非常好的方法。原文用英文进行解释,在此我们将其翻译成汉语。该方法的核心是将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。

首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]

double findKth(int a[], int m, int b[], int n, int k)
{
    //always assume that m is equal or smaller than n
    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]);
    //divide k into two parts
    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])
        return findKth(a, m, b + pb, n - pb, k - pb);
    else
        return a[pa - 1];
}

class Solution
{
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n)
    {
        int total = m + n;
        if (total & 0x1)
            return findKth(A, m, B, n, total / 2 + 1);
        else
            return (findKth(A, m, B, n, total / 2)
                    + findKth(A, m, B, n, total / 2 + 1)) / 2;
    }
};
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:55968次
    • 积分:2174
    • 等级:
    • 排名:第17451名
    • 原创:162篇
    • 转载:9篇
    • 译文:0篇
    • 评论:13条
    文章分类
    最新评论