题目描述:(题目链接)
There are two sorted arrays nums1 and nums2 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)).
解题思路:
该问题可以被转化为在两个数组中找第K小的问题,
假设两个数组A和B,A.size() > k / 2,B.size() > k / 2:
1. if A[k / 2 - 1] < B[k / 2 - 1], 说明A[0] ~ A[k / 2 - 1] 出现在A和B合并数组的Top k中;
2. if A[k / 2 - 1] > B[k / 2 - 1], 与情况1类似
3. if A[k / 2 - 1] = B[k / 2 - 1], 返回A[k / 2 - 1] 或者 B[k / 2 - 1];
当然还需要考虑一些边界情况:
1. 如果A或者B有一个为空, 返回B[k - 1] 或者 A[k - 1]
2. 如果k == 1, 返回min(A[0], B[0])
C语言描述:
int min(int a, int b) { if (a > b) { return b; } return a; } int findKth(int *nums1, int m, int *nums2, int n, int k) { if (m > n) { return findKth(nums2, n, nums1, m, k); } if (m == 0) { return nums2[k - 1]; } if (k == 1) { return min(nums1[0], nums2[0]);} int a = min(k / 2, m); int b = k - a; if (nums1[a - 1] < nums2[b - 1]) { return findKth(nums1 + a, m - a, nums2, n, k - a); } else if (nums1[a - 1] > nums2[b - 1]) { return findKth(nums1, m, nums2 + b, n - b, k - b); } else { return nums1[a - 1]; } } double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { int total = (nums1Size + nums2Size); if (total & 1) { return findKth(nums1, nums1Size, nums2, nums2Size, total / 2 + 1); } else { return (findKth(nums1, nums1Size, nums2, nums2Size, total / 2) + findKth(nums1, nums1Size, nums2, nums2Size, total / 2 + 1)) / 2.0; } }
2015-10-03更新,重新用C++写了一遍,vector用的不熟,LeetCode编译器好像不支持C++ 14!
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int nums1Size = nums1.size(); int nums2Size = nums2.size(); int total = (nums1Size + nums2Size); if (total & 1) { return findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2 + 1); } else { return (findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2) + findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2 + 1)) / 2.0; } } int findKth(vector<int>::iterator nums1, int m, vector<int>::iterator nums2, int n, int k) { if (m > n) { return findKth(nums2, n, nums1, m, k); } if (m == 0) { return *(nums2 + k - 1); } if (k == 1) { return min(*nums1, *nums2);} int a = min(k / 2, m); int b = k - a; if (*(nums1 + a - 1) < *(nums2 + b - 1)) { return findKth(nums1 + a, m - a, nums2, n, k - a); } else if (*(nums1 + a - 1) > *(nums2 + b - 1)) { return findKth(nums1, m, nums2 + b, n - b, k - b); } else { return *(nums1 + a - 1); } } };