leetcode 4. Median of Two Sorted Arrays(Hard)

来源:互联网 发布:软件编程工资多少 编辑:程序博客网 时间:2024/06/09 17:57

Problem :
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)).

Example:
Example 1:
nums1 = [1, 3], nums2 = [2]
The median is 2.0

Example 2:
nums1 = [1, 2], nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

Algorithm:
1、本题的时间复杂度是O(log (m+n)),根据时间复杂度我们很容易得出,我们每次要必须排除一半的元素,才能满足题目要求。因此,此题的思路与二分查找相似。
2、由于这题是另一类题目(找出两组序列中第K大的元素)的一种特殊情况,因此,在解题时,我把此题按照一般化的情况来求解,下面给出具体算法思路:
(1)保证A序列的长度小于B序列的长度,原因在下面说明;
(2)如果A序列长度为0,表明A中已经没有元素(因为步骤(1)的处理,所以必定A先变为0),这时第K大的元素即为B中的第K个元素;
(3)如果K = 1,表明所求元素即为A、B序列当前首部的最小值;
(4)若上面3条均不满足,我们令M1等于K/2与A序列长度的最小值,这样,我们就能保证:要么每次排除K/2个元素,使得总时间复杂度为O(log(K)),即题意的要求;要么排除掉A序列中所有元素,从而回到步骤(2)得出答案。注意,由于步骤(1)的处理,K - M1必然不会超过B序列的总长度;
(5)若A[BE1+M1-1] = B[BE2+M2-1],则其中任意一个即为所求答案,将其返回;
(6)若A[BE1+M1-1] < B[BE2+M2-1],则我们把A中这些较小的元素排除掉,因为它们肯定比K小(步骤(4))。这样我们只需要找两个新序列中第K-M1小的元素即可。根据步骤(4),我们排除了K/2(或A序列长度)个元素,满足时间复杂度要求;
(7)A[BE1+M1-1] > B[BE2+M2-1]的情况类似。

Code:

double find_kth_num(vector<int>& v1,int be1, int en1, vector<int>& v2, int be2, int en2, int k){    int n1 = en1 - be1;    int n2 = en2 - be2;    if(n1 > n2) return find_kth_num(v2, be2, en2, v1, be1, en1, k);    if(n1 == 0) return v2[be2 + k - 1];    if(k == 1) return min(v1[be1],v2[be2]);    int m1 = min(k / 2, n1), m2 = k - m1;    if(v1[be1 + m1 - 1] == v2[be2 + m2 - 1]) return v1[be1 + m1 - 1];    if(v1[be1 + m1 - 1] < v2[be2 + m2 - 1])        return find_kth_num(v1, be1 + m1, en1, v2, be2, en2, k - m1);    else        return find_kth_num(v1, be1, en1, v2, be2 + m2, en2, k - m2);}class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int n1 = nums1.size();        int n2 = nums2.size();        if((n1 + n2) % 2)            return find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2 + 1); //第k个元素(k从1开始)         else            return (find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2)                     + find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2 + 1)) / 2;     }};
0 0
原创粉丝点击