leetcode链表--13、median-of-two-sorted-arrays(两个排序数组的中位数,时间复杂度)

题目描述

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

题目解析:本题关键之处在于时间复杂度要求为O(log(m+n)),本题如果采用合并并排序两数组的方式,时间复杂度为O((m+n)*log(n+m))但是在牛客网上提交也通过了

 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(int A[], int m, int B[], int n) {
 4         int tmp[m+n];
 5         memcpy(tmp,A,sizeof(int)*m);
 6         memcpy(tmp+m,B,sizeof(int)*n);
 7
 8         sort(tmp,tmp+n+m);
 9
10         double median=(double) ((n+m)%2? tmp[(n+m)>>1]:(tmp[(n+m-1)>>1]+tmp[(n+m)>>1])/2.0);
11         return median;
12
13     }
14 };

本题正确解法为:
该方法的核心是将原问题转变成一个寻找第k小数的问题(假设两个原序列升序排列),这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的问题,原问题也得以解决。
对于找第k小的元素,采用二分查找的方式,进行查找:
1)首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。
2)这两个元素比较共有三种情况:>、<和=。
如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。
证明也很简单,可以采用反证法。假设A[k/2-1]大于合并之后的第k小值,我们不妨假定其为第(k+1)小值。由于A[k/2-1]小于B[k/2-1],所以B[k/2-1]至少是第(k+2)小值。但实际上,在A中至多存在k/2-1个元素小于A[k/2-1],B中也至多存在k/2-1个元素小于A[k/2-1],所以小于A[k/2-1]的元素个数至多有k/2+ k/2-2,小于k,这与A[k/2-1]是第(k+1)的数矛盾。
当A[k/2-1]>B[k/2-1]时存在类似的结论。
当A[k/2-1]=B[k/2-1]时,我们已经找到了第k小的数,也即这个相等的元素,我们将其记为m。
由于在A和B中分别有k/2-1个元素小于m,所以m即是第k小的数。(这里可能有人会有疑问,如果k为奇数,则m不是中位数。这里是进行了理想化考虑,在实际代码中略有不同,是先求k/2,然后利用k-k/2获得另一个数。)
通过上面的分析,我们即可以采用递归的方式实现寻找第k小的数。此外我们还需要考虑几个边界条件:
如果A或者B为空,则直接返回B[k-1]或者A[k-1];
如果k为1,我们只需要返回A[0]和B[0]中的较小值;
如果A[k/2-1]=B[k/2-1],返回其中一个;
定义pa = min(k/2,m)  pb = k - pa;
if (a[pa - 1] < b[pb - 1])  则说明对于数组a 其 0-pa均处于第k小的数左侧,则第k小的数应为 findKth(a + pa, m - pa, b, n, k - pa);
if (a[pa - 1] > b[pb - 1])   则说明对于数组b 其 0-pb均处于第k小的数左侧,则第k小的数应为 findKth(a, m, b + pb, n - pb, k - pb);
如果相等,则返回其中一个  a[pa - 1]

 1 class Solution {
 2 public:
 3 double findKth(int a[], int m, int b[], int n, int k)
 4     {
 5         //always assume that m is equal or smaller than n
 6         if (m > n)
 7             return findKth(b, n, a, m, k);
 8         if (m == 0)
 9             return b[k - 1];
10         if (k == 1)
11             return min(a[0], b[0]);
12         //divide k into two parts
13         int pa = min(k / 2, m), pb = k - pa;
14         if (a[pa - 1] < b[pb - 1])
15             return findKth(a + pa, m - pa, b, n, k - pa);
16         else if (a[pa - 1] > b[pb - 1])
17             return findKth(a, m, b + pb, n - pb, k - pb);
18         else
19             return a[pa - 1];
20     }
21     double findMedianSortedArrays(int A[], int m, int B[], int n) {
22         int total = m + n;
23         if (total & 0x1)
24             return findKth(A, m, B, n, total / 2 + 1);
25         else
26             return (findKth(A, m, B, n, total / 2)
27                     + findKth(A, m, B, n, total / 2 + 1)) / 2;
28     }
29 };

我们可以看出,代码非常简洁,而且效率也很高。在最好情况下,每次都有k一半的元素被删除,所以算法复杂度为logk,由于求中位数时k为(m+n)/2,所以算法复杂度为log(m+n)。

时间: 2024-10-21 08:26:23

leetcode链表--13、median-of-two-sorted-arrays(两个排序数组的中位数,时间复杂度)的相关文章

[LeetCode]4. Median of Two Sorted Arrays两个排序数组合并后的中位数

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 解法一:不考虑时间复杂度限制在O(log(m+n)),则将两个数组遍历一遍即可以组合成一个排好序的数组,然后取数组的中位数即可,时间复杂度O(m+n): c

[LeetCode] 4. Median of Two Sorted Arrays 两个有序数组的中位数

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 求两个有序数组的中位数,并限制了时间复杂度O(log (m+n)),看到这个时间复杂度,自然想到用二分搜索Binary Search. 对于一个长度为n的已

[LintCode] Median of Two Sorted Arrays 两个有序数组的中位数

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. Have you met this question in a real interview? Example Given A=[1,2,3,4,5,6] and B=[2,3,4,5], the median is 3.5. Given A=[1,2,3] and B=[4,5],

[LeetCode] Median of Two Sorted Arrays 两个有序数组的中位数

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). http://www.acmerblog.com/leetcode-median-of-two-sorted-arrays-5330.html http:/

Median of Two Sorted 求两个有序数组的中位数

中位数是把一个数的集合划分为两部分,每部分包含的数字个数相同,并且一个集合中的元素均大于另一个集合中的元素. 因此,我们考虑在一个任意的位置,将数组A划分成两部分.i表示划分数组A的位置,如果数组A包含m个元素,则划分位置有m+1种情况.因此,i的取值范围是0~m. 当i=0时,表示left_A为空:当i=m时,表示right_A为空. 同理,我们也可以划分B数组: 我们把left_A和left_B放到一个集合中,把right_A和right_B放到一个集合中. 如果想要获得中位数,要保证len

LeetCode4 :median of two sorted arrays---求两个有序数组的中位数

class Solution { public: double FindKthNumber(vector<int> numbers1, vector<int>numbers2, int len1, int len2, int start1, int start2, int k){ if (len1 > len2) return FindKthNumber(numbers2, numbers1, len2, len1, start2, start1, k); if (len1

leetcode题解:Search in Rotated Sorted Array(旋转排序数组查找)

题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no du

leetcode 题解:Remove Duplicates from Sorted Array(已排序数组去重)

题目: Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. For example,Given input array A

leetcode.C.4. Median of Two Sorted Arrays

4. Median of Two Sorted Arrays 这应该是最简单最慢的方法了,因为本身为有序,所以比较后排序再得到中位数. 1 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { 2 int numsSize = nums1Size + nums2Size; 3 int *nums = (int*)malloc(sizeof(int)*numsSize); 4 do

[LeetCode] 4. 两个排序数组的中位数

该题的难度分级是Hard,那么难在哪里呢?我们先来看题目. 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 示例 1: nums1 = [1, 3] nums2 = [2] 中位数是 2.0 示例 2: nums1 = [1, 2] nums2 = [3, 4] 中位数是 (2 + 3)/2 = 2.5 当你看到要求的时间复杂度为O(log (m+n)),你想到了什么?没错,二分法. 从示