leetcode 4 :寻找两个正序数组的中位数

leetcode 4 :寻找两个正序数组的中位数

1. 题目

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。

2. 示例:

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

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

3. 自己的解决方法

主要用到快速排序,进行排序,然后找中位数

快速排序

  1. 通过一趟排序将要排序的数据分割成独立的两部分,
    其中一部分的所有数据都比另外一部分的所有数据都要小,
    然后递归进行,以此达到整个数据变成有序序列。

  2. 思想:找出一个基准 pivot 然后把数据分成两部分 然后再递归

  3. 时间复杂度:平均O(nlog(n)),最坏:O(n^2))
    空间复杂度:O(log(n))
    是否稳定:不稳定

     /* 快速排序处理 */
     void mySwap(int *i, int *j)
     {
     	int tmp = *i;
     	*i = *j;
     	*j = tmp;
     }
    
     int partion(int arr[], int low, int high)
     {
     	int pivot = arr[low];
     	while (low < high)
     	{
     		while (low < high && arr[high] >= pivot)
     		{
     			high--;
     		}
     		mySwap(&arr[low], &arr[high]);
     
     		while (low < high && arr[low] <= pivot)
     		{
     			low++;
     		}
     		mySwap(&arr[low], &arr[high]);
     
     	}
     	return low;
     }
     
     void q_sort(int arr[], int low, int high)
     {
     	if (low < high)
     	{
     		int pivot = partion(arr, low, high);
     		q_sort(arr, low, pivot - 1);
     		q_sort(arr, pivot + 1, high);
     	}
     }
     
     void quick_sort(int arr[], int len)
     {
     	q_sort(arr, 0, len - 1);
     }
     
     /* 寻找中位数 */
     double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size)
     {
     	int iAllSize = nums1Size + nums2Size;
     	/* 判断是否都为空 */
     	if(0 == iAllSize)
     	{
     		return 0;
     	}
     	
     	
     	int aiAllArr[iAllSize];
     	memset(aiAllArr, 0, iAllSize);
     	
     	int iLoop = 0;
     	int iLoop2 = 0;
     	
     	/* 如果一个数组为空的处理 */
     	if(0 == nums1Size)
     	{
     		if(0 == nums2Size)
     		{
     			return 0;
     		}
     		
     		if(0 == nums2Size%2)
     		{
     			return (double)(nums2[nums2Size/2] + nums2[nums2Size/2 - 1])/2;
     		}else
     		{
     			return (double)nums2[nums2Size/2];
     		}
     	}
     	
     	/* 如果一个数组为空的处理 */
     	if(0 == nums2Size)
     	{
     		if(0 == nums1Size)
     		{
     			return 0;
     		}
     		
     		if(0 == nums1Size%2)
     		{
     			return (double)(nums1[nums1Size/2] + nums1[nums1Size/2 - 1])/2;
     		}else
     		{
     			return (double)nums1[nums1Size/2];
     		}
     	}
     	
     	/* 两个数组合并成一个数组处理 */
     	for(iLoop = 0; iLoop < nums1Size; iLoop ++)
     	{
     		aiAllArr[iLoop] = nums1[iLoop];
     	}
     	
     	for(iLoop2 = 0 ;iLoop2 < nums2Size; iLoop2 ++)
     	{
     		aiAllArr[iLoop] = nums2[iLoop2];
     		iLoop ++;
     	}
     	
     	/* 对总的数组快速排序 */
     	quick_sort(aiAllArr, iAllSize);
     	
     	/* 找出中位数 */
     	if(0 == iAllSize%2)
     	{
     		return (double)(aiAllArr[iAllSize/2] + aiAllArr[iAllSize/2 - 1])/2;
     	}else
     	{
     		return (double)aiAllArr[iAllSize/2];
     	}
     	
     }
    

4. 标准答案

#include <stdio.h>
#include <vector>
using namespace std;

#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))

class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		int n = nums1.size();
		int m = nums2.size();

		if (n > m)  //保证数组1一定最短
		{
			return findMedianSortedArrays(nums2, nums1);
		}

		// Ci 为第i个数组的割,比如C1为2时表示第1个数组只有2个元素。LMaxi为第i个数组割后的左元素。RMini为第i个数组割后的右元素。
		int LMax1, LMax2, RMin1, RMin2, c1, c2, lo = 0, hi = 2 * n;  //我们目前是虚拟加了'#'所以数组1是2*n长度

		while (lo <= hi)   //二分
		{
			c1 = (lo + hi) / 2;  //c1是二分的结果
			c2 = m + n - c1;

			LMax1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) / 2];
			RMin1 = (c1 == 2 * n) ? INT_MAX : nums1[c1 / 2];
			LMax2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) / 2];
			RMin2 = (c2 == 2 * m) ? INT_MAX : nums2[c2 / 2];

			if (LMax1 > RMin2)
				hi = c1 - 1;
			else if (LMax2 > RMin1)
				lo = c1 + 1;
			else
				break;
		}
		return (max(LMax1, LMax2) + min(RMin1, RMin2)) / 2.0;
	}
};


int main(int argc, char *argv[])
{
	vector<int> nums1 = { 2,3, 5 };
	vector<int> nums2 = { 1,4,7, 9 };
	
	Solution solution;
	double ret = solution.findMedianSortedArrays(nums1, nums2);
	return 0;
}

链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/4-xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-shu/

猜你喜欢

转载自blog.csdn.net/lqy971966/article/details/107341477