leetcode4. Median of Two Sorted Arrays
题意:
有两个已排序的数组nums1和nums2,数组大小分别为m和n。
找到两个排序数组的中位数。整体运行时间复杂度应为O(log(m + n))。
思路:
感觉这道题还是有点难的,主要是对时间复杂度要求有点无法适应。
找到两个已排序数组的中位数。
其实理解成一般性的问题的话,就是找到第k个大小的数字。
不做要求的话,可以直接归并排序的思路可以直接找出第k大的数字,但是要是在n很大而且k无线接近于n的时候,复杂度还是很高的。在优化一下话,可以先算k在n/2的左边还是右边在右边的话,可以反向找,这样最差的情况是O(n/2)=O(n),还是O(n),但是起码给了自己一个二分的思路。
log的复杂度一般都是二分的。想上面一样要是继续二分下去的,是可以让复杂度变成Log(n)的。
我们要找到两个数组合并起来第k大的元素的话,我们可以先试想一种最特殊的情况,便于理解,就是A,B的前面各自占有的K/2全都是一样的,那么结果不就是(A[K/2]+B[K/2])/2吗?要是A[K/2] < B[K/2] ,画一个图理解马上就可以发现,两个数组合并之后,真正的第k大的元素应该在B[K/2]的左侧或者A[K/2]的右侧,我们可以吧A[K/2]左侧的元素(假设舍去了i个元素)舍去,因为全都是比k要小的元素。然后我们继续寻找剩下的数组中第(K-i)大的元素。这样的循环复杂度是可以认为是O(log(m + n))
的。代码实现的时候要注意边界的情况。
ac代码:
C++
class Solution {
public:
int getkth(vector<int>& s,vector<int> &l,int k){
if(s.size()>l.size()) return getkth(l,s,k);
if(!s.size()) return l[k-1];
if(k==1) return min(s[0],l[0]);
int i=min((int)s.size(),k/2),j=min((int)l.size(),k/2);
if(s[i-1]>l[j-1]){
vector<int> next;
for(int u=j;u<l.size();u++)
next.push_back(l[u]);
//copy(l.begin()+j,l.end(),next.begin());
return getkth(s,next,k-j);
}
else{
vector<int> next;
for(int u=i;u<s.size();u++)
next.push_back(s[u]);
//copy(s.begin()+i,s.end(),next.begin());
return getkth(next,l,k-i);
}
return 0;
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int l=(nums1.size()+nums2.size()+1)/2;
int r=(nums1.size()+nums2.size()+2)/2;
return (getkth(nums1,nums2,l)+getkth(nums1,nums2,r))/2.0;
}
};
python
class Solution:
def findkth(self,nums1,nums2,k):
if len(nums1)>len(nums2):
return self.findkth(nums2,nums1,k)
if len(nums1) == 0:
return nums2[k-1]
if k == 1:
return min(nums1[0],nums2[0])
n = min(k//2 ,len(nums1))
m = min(k//2 ,len(nums2))
if nums1[n - 1] > nums2[m - 1]:
return self.findkth(nums1,nums2[m:],k-m)
else:
return self.findkth(nums1[n:],nums2,k-n)
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
k1 = len(nums1)+len(nums2)+1
k2 = len(nums1)+len(nums2)+2
return (self.findkth(nums1,nums2,k1//2)+self.findkth(nums1,nums2,k2//2))/2