Leetcode(C++)——4. 寻找两个有序数组的中位数

4. 寻找两个有序数组的中位数

①题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

②示例

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

③解法

方法一:数组合并取中位数

将nums1和nums2合并成一个有序数组,然后直接取中位数。

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        int l1 = nums1.size(), l2 = nums2.size();
        int p1 = 0, p2 = 0;
        vector nums;
		for(int i = 0; i < l1 + l2; i++) {
        	int n1 = p1 >= l1? 99999999 : nums1[p1];
        	int n2 = p2 >= l2? 99999999 : nums2[p2];
			if(n1 > n2) {
				nums.push_back(n2);
				p2++;
			}
			else {
				nums.push_back(n1);
				p1++;
			}
		} 
		if((l1 + l2) % 2 == 0) {
			double res = (nums[(l1 + l2)/2] + nums[(l1 + l2) / 2 - 1]) / 2.0;
			return res;
		}
		else
			return nums[(l1 + l2)/2];
    }
};

Leetcode的测试结果:
在这里插入图片描述

方法二:递归法

主要是利用中位数的性质,把2个数组分别再分成2部分,逐渐调整分割位置,直到找到所有比中位数小的数。具体可以参考下文:
原文链接

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        int m = nums1.size(), n = nums2.size();
		if(m > n) {
        	vector temp = nums1; nums1 = nums2; nums2 = temp;
        	int tmp = m; m = n; n = tmp; 
		} 
		//print(nums1);
		//print(nums2);
		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]) {
				cout<<"judge1: "< iMin && nums1[i - 1] > nums2[j]) {
				//cout<<"judge2: "<

Leetcode的测试结果:
在这里插入图片描述

方法三:分治法(方法二的优化)

和方法二类似,但是解决了数组奇偶性的问题。具体原文链接如下:
原文链接

class Solution {
public:
	double MidofArray(vector &nums) {
		int mid = nums.size() / 2;
		int flag = ! (nums.size() % 2);
		return (nums[mid] + nums[mid - flag]) / 2.0;
	} 
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
        if(nums1.size() == 0)
			return MidofArray(nums2);
		if(nums2.size() == 0)
			return MidofArray(nums1);
		int n = nums1.size(), m =nums2.size();
		if(n > m)
			return findMedianSortedArrays(nums2, nums1);
		int L1, L2, R1, R2, c1, c2, lo = 0, hi = 2 * n;
		while(lo <= hi) {
			c1 = (lo + hi) / 2;
			c2 = m + n - c1;
			L1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) /2];
			R1 = (c1 == 2 * n) ? INT_MAX : nums1[c1 /2];
			L2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) /2];
			R2 = (c2 == 2 * m) ? INT_MAX : nums2[c2 /2];
			
			if(L1 > R2)
				hi = c1 - 1;
			else if(L2 > R1)
				lo = c1 + 1;
			else 
				break;
		} 
		return (max(L1, L2) + min(R1, R2)) / 2.0;
    }
};

Leetcode的测试结果:
在这里插入图片描述

④总结

这道题一开始只会暴力法,看了递归和分治好久才看懂,好好学习天天向上!

你可能感兴趣的:(Leetcode(C++))