求俩个有序序列的中位数 ,和求众数问题
2013-04-15 19:27
375 查看
2010-03-31 10:43
比较两个有序表各自的中位数 a,b 假设 a>=b,那么这2n个数的中位数一定不在第一个序列>a的那部分上,因为第一个序列中有n/2-1个数比a小,第二个序列中至少有n/2个数比a小(a>=b),同理,中位数一定不在第二个序列<b的那部分。这样每个序列中各排除了n/2, 于是变为了n/2的两个有序序列中求中位数。当序列长度为一时,较小数即为所求中位数。
return j;
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 ; int B ; 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 ; 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 ;
//求众数及重数 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;
}
相关文章推荐
- 统计工龄 模拟EXCEL排序 银行排队问题之单队列多窗口问题 银行业务队列简单模拟 堆栈操作合法性 两个有序序列的中位数
- 包信封问题 以及 最长有序子序列问题
- PAT 两个有序序列的中位数
- 两个有序序列的中位数
- 求两个有序序列合并成新有序序列的中位数,求第k小数
- 5-7 两个有序序列的中位数 (25分)
- 两个有序序列的中位数
- 递归分治问题之找出两个有序序列的中间值
- PAT1019. 两个有序序列的中位数(25)
- 数据结构_中国大学MOOC(慕课)——两个有序链表序列的合并问题
- 5-53 两个有序序列的中位数 (25分)
- 求两个等长有序数组中位数算法问题
- 2-13. 两个有序序列的中位数(25)
- 2-13. 两个有序序列的中位数(25)(ZJU_PAT 链表 | 数组 )
- 【分步详解】两个有序数组中的中位数和Top K问题
- 浙江大学PAT上机题解析之2-13. 两个有序序列的中位数
- 关于在一个序列中寻找中位数和第K大的数(在两个等长有序数组中寻找中位数)
- Programming Ability Test学习 2-13. 两个有序序列的中位数(25)
- 每天作死一道题——两个有序序列的中位数
- 求两个等长有序序列的中位数