标签:
题目:
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)).
题意:
有两组长度分别为 m 和 n 的已排序数组 nums1 和 nums2 ,找到两组数的中间值,时间复杂度需为 O(log(m+n)) 。
其中中间值是指:对于长度为奇数的数组如 {1,3,4} ,中间值为3;对于长度为偶数的数组 {1,2,5,7} ,中间值为 (2+5)/2.0=3.5。
解题思路(借用讨论里热门第一的回答思路,确实佩服这个人将算法题用数学思路分析):
1. 对于长度为 m 的已排序数组 A,我们可以用下标 i 来将其分成两组:{A[0], ... A[i-1], | A[i], ... A[m]}。
共有 m+1 种分法 ( i = 0~m )。且数组中左边的 i 个元素全部不大于 A[i] ,右边的 m - i 个元素全部不小于 A[i]。
同理可由 j 来拆分长度为 n 的已排序数组B,由 i + j 来拆分 A 和 B 合并生成的数组 Result 。
2. 若要得到中间值,则需要找到相应的 i 和 j ,满足如下两个条件:
(1) i + j = m - i + n - j ( m+n 为偶数的情况 )
或 i + j = m - i + n - j + 1( m+n 为奇数的情况 );
(2) A[0] ~ A[i-1] 与 B[0] ~ B[j-1] 的所有值全部不大于 A[i] ~ A[m] 与 B[j] ~ B [n] 的所有值。
3. 上述两条件等价于:
(1) 假设 n > m,j = ( m + n + 1) / 2 - i;
(2) A[i-1] < B[j] 且 B[j-1] < A[i] 。
还需考虑到边界值 i = 0 或 m , j = 0 或 n 的情况。
4. [编码思路] 接下来可以利用二分查找法帮助获取中间值 (由题目的时间复杂度要求可联想到二分查找法) 。
(1) set imin = 0, imax = m, start searching in ( imin, imax);
(2) set i = ( imin + imax ) / 2, half = ( m + n + 1)/2, j = half - i;
(3) if ( A[i-1] > B[j] ) imax = i - 1 ; //搜索区域缩小在 i 左半边
else if ( A[i] < B[j-1] ) imin = i + 1 ; //搜索区域缩小在 i 右半边
else break;
(4) if ( 0==i ) num1 = B[j-1]; // i==0 时 j = half, 即 B[j-1] 为合并后的 Result 左边最大值
else if ( 0==j ) num1 = A[i-1]; // j==0 时 A[i-1] 为 Result 左边最大值
else num1 = max( B[j-1], A[i-1]); //其他情况下取 Result 左边最大值
// m+n 为奇数时直接返回 num1 即可
if( (m+n)%2==1 )
return num1;
if( m==i ) num2 = B[j]; // i==m 时,由于前面已经引入 j=0 时取 num1 = A[i-1]的情况,需要此时取 num2 = B[j]
else if ( n == j ) num2 = A[i]; //j==n时同理取 num2 = A[i]
else num2 = min( B[j], A[i] ); //其他情况下取 Result 右边部分最小值
return ( ( num1 + num2 )/2.0 );
C#代码:
public class Solution { public double FindMedianSortedArrays(int[] nums1, int[] nums2) { int m = nums1.Length, n = nums2.Length; if (m > n) return FindMedianSortedArrays(nums2, nums1); int imin = 0, imax = m, half = (m + n + 1) / 2; int i = 0, j = 0; while (imin <= imax) { i = (imin + imax) / 2; j = half - i; if (i > 0 && j < n && nums1[i - 1] > nums2[j]) imax = i - 1; else if (j > 0 && i < m && nums2[j - 1] > nums1[i]) imin = i + 1; else break; } double num1 = 0, num2 = 0; if (0 == i) num1 = nums2[j - 1]; else if (0 == j) num1 = nums1[i - 1]; else num1 = Math.Max(nums2[j - 1], nums1[i - 1]); if ((m + n) % 2 == 1) return num1; if (m == i) num2 = nums2[j]; else if (n == j) num2 = nums1[i]; else num2 = Math.Min(nums2[j], nums1[i]); return ((num1 + num2) / 2); } }
LeetCode - 4. Median of Two Sorted Arrays
标签:
原文地址:http://www.cnblogs.com/xquancnblogs/p/5097313.html