更多LeetCode题解
我的解法
这是一道很简单的两个有序向量的二路归并问题。
由于nums1
和nums2
都是有序的,只需要不断的比较它们的首元素,合并为一个有序的向量,再输出这个向量的中间值。
C++
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
double res;
vector<int> merged;
for (int i = 0, j = 0; i < nums1.size() || j < nums2.size();) {
if ( i < nums1.size() && (j >= nums2.size() || nums1[i] < nums2[j]) ) {
merged.push_back(nums1[i++]);
}
if ( j < nums2.size() && (i >= nums1.size() || nums1[i] >= nums2[j]) ) {
merged.push_back(nums2[j++]);
}
}
if (merged.size() % 2) {
res = static_cast<double>(merged[merged.size() >> 1]);
}
else {
res = static_cast<double>(merged[merged.size() >> 1] + merged[(merged.size() >> 1) - 1]) / 2;
}
return res;
}
};
我的方法的时间复杂度低于84%的cpp提交。
官方的解答时间复杂度更低,比较复杂,具体可以参考
https://leetcode.com/articles/median-of-two-sorted-arrays/
中文版:https://leetcode-cn.com/articles/median-of-two-sorted-arrays/
//O(log(m+n))
class Solution {
public:
double findMedianSortedArrays(vector<int> & nums1, vector<int> & nums2) {
int sz = nums1.size() + nums2.size();
if (sz == 0) throw runtime_error("both empty");
double m = findKth(nums1.begin(), nums1.end(),
nums2.begin(), nums2.end(), (sz + 1) / 2);
if (sz % 2 == 0)
m = (m + findKth(nums1.begin(), nums1.end(),
nums2.begin(), nums2.end(), (sz + 2) / 2)) / 2.0;
return m;
}
private:
// find k-th smallest element in the merged array of a[i:j) and b[p:q)
template <typename RandIt>
double findKth(RandIt i, RandIt j, RandIt p, RandIt q, int k) {
if (i == j) return *(p + k - 1);
if (p == q) return *(i + k - 1);
if (k == 1) return min(*i, *p); // none is empty
int m = min(j - i, k / 2), n = min(q - p, k / 2);
if (*(i + m - 1) < *(p + n - 1))
return findKth(i + m, j, p, q, k - m);
else
return findKth(i, j, p + n, q, k - n);
}
// RandIt - RandIt is It::difference_type,
int min(int i, int j) { return i < j ? i : j; }
};
//O(log(min(m,n)))
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
if (m > n) {
nums1.swap(nums2);
m = m ^ n;
n = m ^ n;
m = m ^ n;
}
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if (i < iMax && nums2[j - 1] > nums1[i]) {
iMin = i + 1;
}
else if (i > iMin && nums1[i - 1] > nums2[j]) {
iMax = i - 1;
}
else {
int maxLeft = 0;
if (i == 0) { maxLeft = nums2[j - 1]; }
else if (j == 0) { maxLeft = nums1[i - 1]; }
else { maxLeft = max(nums1[i - 1], nums2[j - 1]); }
if ((m + n) % 2 == 1) { return maxLeft; }
int minRight = 0;
if (i == m) { minRight = nums2[j]; }
else if (j == m) { minRight = nums1[i]; }
else { minRight = min(nums1[i], nums2[j]); }
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
};
简便的方法
利用python的sort方法,再结合python可以简单地将两个列表相加,使得代码十分简单。
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
newNums = nums1 + nums2
newNums.sort()
value = len(newNums)
if (value % 2) == 0:
num1 = newNums[value//2 - 1]
num2 = newNums[value//2]
return (num1 + num2)/2
else:
return float(newNums[value//2])