这个题目里说O(log(m+n)),还以为和严格,结果m+n时间的居然过了。。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
double cur_num = 0;
int count = 0;
int medium = (nums1.size() + nums2.size()) / 2+1;
bool is_odd = ((nums1.size() + nums2.size()) % 2 == 1);
int itr1 = 0;
int itr2 = 0;
while (true) {
int temp = 0;
if (count == medium ) {
break;
}
if (itr1 < nums1.size() && itr2 < nums2.size()) {
if (nums1[itr1] < nums2[itr2]) {
temp = nums1[itr1];
itr1++;
count++;
}
else {
temp = nums2[itr2];
itr2++;
count++;
}
}
else if (itr1 >nums1.size() && itr2>nums2.size()) {
break;
}
else if (itr1 < nums1.size()) {
temp = nums1[itr1];
itr1++;
count++;
}
else {
temp = nums2[itr2];
itr2++;
count++;
}
//update cur_num value
if (!is_odd && count == medium) {
cur_num += temp;
cur_num /= 2;
}
else {
cur_num = temp;
}
}
return cur_num;
}
};
然后是想log(m+n)解法,第一想法就是取两个数组中位数比较,但是思路始终固定在来想把数组规模减半,结果怎么都做不到。
然后找答案,结果居然是把题目一般化,讲中位数条件改成第k大的数,然后将k的规模每次缩小一半。因为本题的k=(m+n)/2,所以时间复杂度是O(log(m+n))的
具体的算法就是在规模较小的数组A中去第k/2大小的数和规模较大的数组B中第k/2的数比较,如果A[k/2-1]<B[k/2-1],那么说明A的前k/2个数都比两个数组的第k个数要小,所以可以排除,同时变成从数组A[k/2]~A[k-1]和B数组中找第k/2大的数
递归终点有三种情况
1.存在空数组,那么从另外一个非空数组里取(如果输入有意义,两个空数组是不会出现的)
2.k=1,那么从两个数组取第一小的数,所以返回A[0]和B[0]中较小的
3.A[k/2-1]=B[k/2-1]那么直接返回该值
细节上其实k/2可能会大于A的数组大小,那就取其中较小的即可,如果出现这种情况其实相当于快到递归终点了,也可以单独判断重点也可以去值是取min(k/2,A.size)即可。
class Solution {
public:
int findKth(vector<int>& nums1, vector<int>& nums2, int s1, int size1, int s2, int size2, int k) {
//make nums1.size() <= nums2.size()
if (size1 > size2) {
return findKth(nums2, nums1, s2, size2, s1, size1, k);
}
if (size1 <= 0 && size2 <= 0) { return 0; }
if (size1 <= 0) {
return nums2[k - 1];
}
else if(size2 <= 0){
return nums1[k - 1];
}
if (k == 1) {
return nums1[s1] <= nums2[s2] ? nums1[s1] : nums2[s2];
}
int itr1 = k/2 < size1 ? k/2 : size1;
int itr2 = k - itr1;
if (nums1[s1 + itr1 - 1] < nums2[s2 + itr2 - 1]) {
return findKth(nums1, nums2, s1 + itr1, size1 - itr1, s2, size2, k - itr1);
}
else if (nums1[s1 + itr1 - 1] > nums2[s2 + itr2 - 1]) {
return findKth(nums1, nums2, s1, size1, s2 + itr2, size2 - itr2, k - itr2);
}
else {
return nums1[s1 + itr1 - 1];
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int size1 = nums1.size();
int size2 = nums2.size();
bool is_odd = (size1 + size2) % 2 == 1;
double result = 0;
if (is_odd) {
result = findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2 + 1);
return result;
}
else {
result += findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2);
result += findKth(nums1, nums2, 0, size1, 0, size2, (size1 + size2) / 2 + 1);
result /= 2;
return result;
}
}
};
收获就是可以将问题一般化,这样可以增加新的递归方式