标签:include
题目不难,关键是边界条件要想清楚。先写一个时间复杂度为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; }
本文出自 “天眼神童的新家” 博客,转载请与作者联系!
标签:include
原文地址:http://tianyanshentong.blog.51cto.com/3356396/1555688