首页 > 代码库 > 查找两个有序序数组(一个递增、一个递减)中第K大的数
查找两个有序序数组(一个递增、一个递减)中第K大的数
题目不难,关键是边界条件要想清楚。先写一个时间复杂度为O(K) 的解法。
#include <iostream> using namespace std; //a[] increase //b[] decrease //use ret_value to return the result //function ret reprsent the error if not 0 int find_k(int a[], int b[], int m, int n, int k, int& ret_value) { if(k<=0 || m<0 || n<0 || k>(m+n)) { return -1; } int i = 0, x = m-1, y = 0; while (i<k && x>=0 && y<=n-1) { if (a[x] > b[y]) { ret_value = a[x]; i++; x--; } else if (a[x] < b[y]) { ret_value = b[y]; i++; y++; } else { //equal ret_value = a[x]; i+=2; x--; y++; } } cout << "x:" << x << endl << "y:" << y << endl << "i:" << i << endl << "v:" << ret_value << endl; i = k-i; if (i > 0) { if (x<0) { ret_value = a[y+i-1]; } else if (y > n-1) { ret_value = a[x-i+1]; } } return 0; } int main () { int a[] = {1,2,3}; int b[] = {6,5,3}; int k=0; cout << "please input the k:"; cin >> k; int value = -1; find_k(a,b,3,3,k,value); cout << value << endl; return 0; }
再附上一个时间复杂服为O(log n)的算法实现,
算法思想是:
每次从两个数组里数 k/2 个数,比较其大小,较大的那个数所在的数组里这 k/2 个数, 肯定在前k大个数里面;
这样就排除了k/2个数,然后再在剩下的数里面找第k/2大的数,循环到找到最后一个数为止。
为了简化一下,假设两个数组都为降序。
注意程序的31~34行,如果不判断相等,当最后还剩一个数的时候,第20行
mid_b = pb + kb -1;
mid_b 会被赋值为一个错误的位置,导致程序陷入死循环
//both a[] b[] decrease int find_k_both_increase_O_log_k(int a[], int b[], int m, int n, int k, int& ret_value) { if(k<=0 || m<0 || n<0 || k>(m+n)) { return -1; } int ka = 0; int kb = 0; int pa = 0; int pb = 0; int mid_a = 0; int mid_b = 0; int i = k; while (i>0 && pa<m && pb<n) { ka = i/2; kb = i-ka; mid_a = pa + ka -1; mid_b = pb + kb -1; if (mid_a<m && mid_b<n) { if (a[mid_a] > b[mid_b]) { ret_value = a[mid_a]; pa = mid_a + 1; i = i - ka; } else if (a[mid_a] < b[mid_b]) { ret_value = b[mid_b]; pb = mid_b + 1; i = i - kb; } else { //equal ret_value = a[mid_a]; return 0; } } cout << "pa:" << pa << endl << "pb:" << pb << endl << "i:" << i << endl; cout <<endl; } if (i > 0) { if (pa > m-1) { ret_value = a[pb-1+i]; } else if (pb > n-1) { ret_value = a[pa-1+i]; } } return 0; }
本文出自 “天眼神童的新家” 博客,转载请与作者联系!
查找两个有序序数组(一个递增、一个递减)中第K大的数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。