LeetCode 4: 寻找两个有序数组的中位数(Median of Two Sorted Arrays)解法汇总


更多LeetCode题解

我的解法

这是一道很简单的两个有序向量的二路归并问题。

由于nums1nums2都是有序的,只需要不断的比较它们的首元素,合并为一个有序的向量,再输出这个向量的中间值。

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])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值