LeetCode OJ Median of Two Sorted Arrays
来源:互联网 发布:淘宝五线谱乐器专营店 编辑:程序博客网 时间:2024/05/17 05:09
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
刚开始的时候看到discuss里有人说可以通过findKthSmallest问题来解决(在两个有序的数组中找到第k小的数),于是在
http://leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html看到了解析就用上了:
大概翻译一下内容:
维持一个等式:i + j = k - 1,其中i是A数组里的第i个数,j是B数组里的第j个数,k是所要求得的第k小的数。注意i和j都是下标(从0开始,小标为-1会特殊处理),而k是第k小,从1开始。
那么:
若找到Bj - 1 < Ai <= Bj,那么Ai即是第k小的数,因为Ai在A数组之前有i个数比Ai小,而Bj在B数组中有j个数比Bj小,那么对于两个数组来说,Ai之前总共就有i + j个数比Ai小,由i + j = k - 1,Ai前有k - 1个数比其小,可知Ai即为第k小的数
若找到Ai - 1 < Bj <= Ai,那么Bj即是第k小的数,理由类似。
若上述两个关系没有成立,那么就继续以ij为点对AB数组进行二分,直到上述两个关系成立。划分的方法如下:
对于Ai和Bj:
若Ai <= Bj,那么必有Ai <= Bj - 1,否则就是Bj - 1 < Ai <= Bj成立了。那么Ai在A数组里有i个比其小的数在前面,而在B数组中Ai最多只有j - 1个数比其小(Bj - 1前有j - 1个数),那么在两个数组中Ai前面就有i + j - 1个数比其小了,由i + j = k - 1,Ai不可能是第k小的数,那么在A数组中比Ai小的数就更不可能了。因此,查找第k小的数的范围应该是排除了A数组中前i + 1个数(Ai前面有i个数,加上Ai本身一共i + 1个)。
若Bj < Ai,同理有Bj <= Ai - 1,分析与上类似,查找范围应该是排除了B数组中前j + 1个数。
class Solution {public: double findMedianSortedArrays(int A[], int m, int B[], int n) { if ((m + n) & 1) // (m + n) is odd return findKthSmallest(A, m, B, n, (m + n) / 2 + 1); else return (findKthSmallest(A, m, B, n, (m + n) / 2) + findKthSmallest(A, m, B, n, (m + n) / 2 + 1)) / 2.0; } int findKthSmallest(int A[], int m, int B[], int n, int k) { int i = (int)((double)m / (m + n) * (k - 1)); int j = (k - 1) - i; // Note: A[-1] = -INF and A[m] = +INF to maintain invariant int Ai_1 = ((i == 0) ? INT_MIN : A[i-1]); // when i == 0, A[i - 1] is INT_MIN int Bj_1 = ((j == 0) ? INT_MIN : B[j-1]); // when j == 0, B[j - 1] is INT_MIN int Ai = ((i == m) ? INT_MAX : A[i]); // when i == m, A[i] is INT_MAX int Bj = ((j == n) ? INT_MAX : B[j]); // when j == n, B[j] is INT_MAX if (Bj_1 < Ai && Ai <= Bj) return Ai; // found if (Ai_1 < Bj && Bj <= Ai) return Bj; // found if (Ai <= Bj) return findKthSmallest(A + i + 1, m - (i + 1), B, j, k - (i + 1)); else return findKthSmallest(A, i, B + j + 1, n - (j + 1), k - (j + 1)); }};后来自己试着用k的复杂度自己做了一次,很多情况要考虑:
class Solution {public: double findMedianSortedArrays(int A[], int m, int B[], int n) { if (m == 0) { // if A's size is zero if (n & 1) return B[n / 2]; else return (B[n / 2 - 1] + B[n / 2]) / 2.0; } if (n == 0) { // if B's size is zero if (m & 1) return A[m / 2]; else return (A[m / 2 - 1] + A[m / 2]) / 2.0; } if ((m + n) & 1) // (m + n) is odd return findKthSmallestForOdd(A, m, B, n, (m + n) / 2 + 1); // (m + n) is even int Apos, Bpos, k; k = (m + n) / 2; Apos = Bpos = -1; while (Apos + Bpos < k - 2) { if (Apos == m - 1) { Bpos++; continue; } else if (Bpos == n - 1) { Apos++; continue; } if (A[Apos + 1] <= B[Bpos + 1]) Apos++; else Bpos++; } int first; // the first number in the pair of the median int firstPos; // the position of the first number bool firstInA; // if the first number is in A if ((Apos == -1) || (Bpos == -1)) { if (Bpos == -1) { // if the k numbers are all in A first = A[Apos]; firstPos = Apos; firstInA = true; } if (Apos == -1) { // if the k numbers are all in B first = B[Bpos]; firstPos = Bpos; firstInA = false; } } else { // if the k numbers are in A and B first = A[Apos] >= B[Bpos] ? A[Apos] : B[Bpos]; firstPos = A[Apos] >= B[Bpos] ? Apos : Bpos; firstInA = A[Apos] >= B[Bpos] ? true : false; } if (firstInA) { if (firstPos == m - 1) { // if the first number is at the end of A, the second one must be at Bpos + 1 return (first + B[Bpos + 1]) / 2.0; } else { if (Bpos == n - 1) return (first + A[firstPos + 1]) / 2.0; // if the number in B are used up, the second number is behind the first one in A int second = B[Bpos + 1] < A[firstPos + 1] ? B[Bpos + 1] : A[firstPos + 1]; // else, the second number is the smaller one between the numbers behind the first one and the Bpos return (first + second) / 2.0; } } else { if (firstPos == n - 1) { return (first + A[Apos + 1]) / 2.0; } else { if (Apos == m - 1) return (first + B[firstPos + 1]) / 2.0; int second = A[Apos + 1] < B[firstPos + 1] ? A[Apos + 1] : B[firstPos + 1]; return (first + second) / 2.0; } } } int findKthSmallestForOdd(int A[], int m, int B[], int n, int k) { int Apos, Bpos; Apos = Bpos = -1; while (Apos + Bpos < k - 2) { if (Apos == m - 1) { // if the number in A are used up Bpos++; continue; } else if (Bpos == n - 1) { // if the number in B are used up Apos++; continue; } if (A[Apos + 1] <= B[Bpos + 1]) Apos++; else Bpos++; } if (Bpos == -1) { // if the k numbers are all in A return A[Apos]; } if (Apos == -1) { // if the k numbers are all in B return B[Bpos]; } return A[Apos] > B[Bpos] ? A[Apos] : B[Bpos]; }};
当然还可以两种方法结合起来,也就是在第一种方法的(m + n)为偶数的情况中先用第一种方法找到组成中位数的前一个数,然后再用第二种方法的思想找到后一个数。比较复杂我还是不做了。
0 0
- LeetCode OJ:Median of Two Sorted Arrays
- LeetCode OJ : Median of Two Sorted Arrays
- LeetCode OJ : Median of Two Sorted Arrays
- LeetCode OJ Median of Two Sorted Arrays
- LeetCode OJ - Median of Two Sorted Arrays (5*)
- [LeetCode OJ][004]Median of Two Sorted Arrays
- LeetCode OJ 4 Median of Two Sorted Arrays
- 【LeetCode OJ 004】Median of Two Sorted Arrays
- LeetCode OJ——Median of Two Sorted Arrays
- LeetCode OJ 4.Median of Two Sorted Arrays
- LeetCode OJ 4. Median of Two Sorted Arrays
- LeetCode OJ(4.Median of Two Sorted Arrays)
- 七、[LeetCode OJ]Median of Two Sorted Arrays
- LeetCode OJ-4.Median of Two Sorted Arrays
- 4. Median of Two Sorted Arrays——LeetCode OJ
- LeetCode: Median of Two Sorted Arrays
- LeetCode Median of Two Sorted Arrays
- leetcode 26: Median of Two Sorted Arrays
- 特征点检测和匹配
- 影响数据库性能的常见因素
- Building Blocks 区间枚举
- Leecode OJ Jump Game
- Linux中的文件描述符与打开文件之间的关系
- LeetCode OJ Median of Two Sorted Arrays
- iOS开发人员必备App开发工具 ifunbox 支持iPhone, iPad和iPod Touch的文件及应用管理神器 使用实例
- win8.1系统 右键桌面鼠标变成圆圈反应很慢
- LeetCode OJ Valid Parentheses
- FZU Problem 2183 简单题(字符串处理)
- LeetCode OJ Rotate Image
- 7. tictactoe终于调试完成
- LeetCode OJ Anagrams
- 通过Tooz在python中实现分布式群组和锁管理