求俩个有序序列的中位数 ,和求众数问题

来源:互联网 发布:mac 阿里旺旺不能用 编辑:程序博客网 时间:2024/05/29 08:25
2010-03-31 10:43

google笔试题两个n维数组logn求中位数问题

两个n维数组,已排序,为升序。设计算法求2n的数中第n大的数。要求分析时间和空间复杂度。

比较两个有序表各自的中位数 a,b 假设 a>=b,那么这2n个数的中位数一定不在第一个序列>a的那部分上,因为第一个序列中有n/2-1个数比a小,第二个序列中至少有n/2个数比a小(a>=b),同理,中位数一定不在第二个序列<b的那部分。这样每个序列中各排除了n/2, 于是变为了n/2的两个有序序列中求中位数。当序列长度为一时,较小数即为所求中位数。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5

#define MAX(a,b) (a)>(b)?(a):(b)

void print_arrat(int A[], int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\t",A[i]);

printf("\n");
}

void swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

int partition(int A[], int start, int end)
{
int x = A[end];
int i = start-1;
int j = start;

for(;j<end;j++)
{
if(A[j]<x)
{
i++;
swap(A+i, A+j);
}
}
swap(A+i+1, A+end);

return i+1;
}

void quick_sort(int A[], int start, int end)
{
if(start<end)
{
int q = partition(A, start, end);
quick_sort(A, start, q-1);
quick_sort(A, q+1, end);
}
}

int count_mid_n(int A[],int a_start,int a_end,int B[],int b_start,int b_end)
{
int ret = 0;
if((a_start==a_end)||(b_start==b_end))
{
printf("min %d %d\n", A[a_start], B[b_start]);
ret = MAX(A[a_start], B[b_start]);
printf("ret is %d\n", ret);
return ret;
}
else
{
int a_mid = (a_start+a_end)/2;
int b_mid = (b_start+b_end)/2;
printf("a_mid is %d, b_mid is %d\n", A[a_mid], B[b_mid]);

if(A[a_mid]>B[b_mid])
return count_mid_n(A, a_start,a_mid,B,b_mid,b_end);
else if(A[a_mid]<B[b_mid])
return count_mid_n(A, a_mid,a_end,B,b_start,b_mid);
else
{
ret = A[a_mid];
return ret;
}
}
}

int main(int argc, char *argv[])
{
int i;
int ret;
srand((unsigned int)time(NULL));
int A[N];
int B[N];

for(i=0;i<N;i++)
A[i] = rand()%100;

for(i=0;i<N;i++)
B[i] = rand()%100;

quick_sort(A, 0, N-1);
quick_sort(B, 0, N-1);

printf("array A is:\n");
print_arrat(A,N);
printf("array B is:\n");
print_arrat(B,N);

ret = count_mid_n(A,0,N-1,B,0,N-1);
printf("mid of 2n is: %d\n", ret);
system("PAUSE");
return 0;
}

#include <iostream>
#include <time.h>

using namespace std;

//Mode是从QuickSort得到
void Mode(int *, int, int, int *);
int Partition(int *, int, int);

//top是下一个众数的下标,top-1是当前众数的下标
//top和Frequence是全局变量,任何一处的赋值都会改变他们的值
//全局变量不作为函数参数,而是在函数内部直接使用
static int top = 0;
//Frequence记录众数的重数
static int Frequence = 0;

int main()
{
    //生成随机数组
    int n = 100;
    int * nData = new int [n];
    srand(time(0));
    for (int i=0;i<n;i++)
        nData [i] = 1 + rand()%n;  //随机域为[1,n];

    //打印
    cout << "随机数组:" << endl;
    for(int j=0;j<n;j++)
        cout << nData[j] << "  ";
    cout << endl;

    //数组nVal存储众数的值,只在[0,top-1]位置存放众数,top-1之后无效
    int * nVal = new int [n];

    //求众数及重数
    Mode(nData,0,n-1, nVal);

    //输出
    cout<<"众数:  ";
    for (int k=0;k<top;k++)
        cout<<nVal[k]<<" ";
    cout << endl;
    cout << "重数:    " << Frequence << endl;

    delete [] nData;
    delete [] nVal;

    return 0;
}

//求数组nData的众数
void Mode(int * nData, int left, int right,int * nVal)
{

    int X = nData[left];

    if(left<right)
    {
        //将小于X的放于其左(未排序),大于X的放于其右(未排序),并返回X在数组中的最终位置。
        int i = Partition(nData,left,right);

        //统计X出现的次数
        int T=0;
        for(int j = left; j <= right; j++)
        {
            if(nData[j]==X)
                    T++;
        }

        if(T==Frequence)
        {
            nVal[top] = nData[i];
            top++;
            //Frequence = T;
        }
        else if (T>Frequence)
        {
            nVal[0] = nData[i];
            top=1;
            Frequence = T;
        }
        if((i-left)>=T)
            Mode(nData,left,i-1,nVal);
        if((right-i)>=T)
            Mode(nData,i+1,right,nVal);
    }
}

//将小于nData[left]的元素放在nData[left]左边,大于nData[left]的元素放在nData[left]右边
//并返回nData[left]的最终位置
//Partition()并没有进行排序,只是分区
int Partition(int * nData, int left, int right)
{
    int i=left, j=right+1;
    int x = nData[left];

    while(true)
    {
        while(nData[++i] < x);
        while(nData[--j] > x);
        if(i >= j) break;
        int temp = nData[i];
        nData[i] = nData[j];
        nData[j] = temp;
       // Swap(nData[i],nData[j]);
    }

    nData[left] = nData[j];
    nData[j] = x;

    return j;
}

原创粉丝点击