两个有序数列A B,长度分别为m,n,求它们的中位数,要求时间复杂度是O(log(m+n)).
解读:即求两数列按序合并后的中位数。
【思路】
1.mine:两个指针i,j分别指向两列的头,当a[i]<b[j]时,i++,反之,j++。当(i+j)==(m+n-2)/2时,即返回当前值。时间复杂度是O(m+n)。
2.others:求第K小的数,核心是当a[k/2-1]<b[k/2-1]时,a[0]——a[k/2-1]必定都小于第K小的数。用递归每次排除掉一半,直到a[k/2-1]=b[k/2-1]时返回该值。
【my code】
尝试用思路1来写代码,当循环结束,要考虑的情况简直太太太多,分不清楚!
因为当m+n是偶数,无法判断前后两个连续大小的值,
当两列有很多相同的值时也无法找到。
放弃。
【other code】
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; } };
题目改成了vector,每次排除一半如何在vector中去掉?疯了。
时间: 2024-11-25 15:24:57