原始题目:
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)).
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]The median is (2 + 3)/2 = 2.5
题目翻译:
求两个规模分别为m,n的有序数组的中位数。该算法的运行时间应不多于O(log(m+n))。
题目分析:
看到这道题想到最简单的解决方法便是,将两个数组归并成一个有序数组,然后求其中位数。其实,这题是一道典型的分治法应用题。分治法简而言之就是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。关于五大常用算法(分治、动态规划、贪心、回溯和分支界定)的简介可见http://blog.csdn.net/wardseptember/article/details/79585996/
第一种解决方法:
class Solution {
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) { // to ensure m<=n
int[] temp = A; A = B; B = temp;
int tmp = m; m = n; n = tmp;
}
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 && B[j-1] > A[i]){
iMin = iMin + 1; // i is too small
}
else if (i > iMin && A[i-1] > B[j]) {
iMax = iMax - 1; // i is too big
}
else { // i is perfect
int maxLeft = 0;
if (i == 0) { maxLeft = B[j-1]; }
else if (j == 0) { maxLeft = A[i-1]; }
else { maxLeft = Math.max(A[i-1], B[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; }
int minRight = 0;
if (i == m) { minRight = B[j]; }
else if (j == n) { minRight = A[i]; }
else { minRight = Math.min(B[j], A[i]); }
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
}
第二种解决方法:
public class MedianofTwoSortedArrays {
// 1 2 3 4
// 2 3 4 5 6 7
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int left = (nums1.length + nums2.length + 1) / 2;
int right = (nums1.length + nums2.length + 2) / 2;
if (left == right) {
return (double) kth(nums1, 0, nums2, 0, left);
}
return (double) (kth(nums1, 0, nums2, 0, left) + kth(nums1, 0, nums2, 0, right)) / 2;
}
private static int kth(int[] a, int aleft, int[] b, int bleft, int k) {
if (aleft >= a.length) {
return b[bleft + k - 1];
}
if (bleft >= b.length) {
return a[aleft + k - 1];
}
if (k == 1) {
return Math.min(a[aleft], b[bleft]);
}
int amid = aleft + k / 2 - 1;
int bmid = bleft + k / 2 - 1;
int aval = amid >= a.length ? Integer.MAX_VALUE : a[amid];
int bval = bmid >= b.length ? Integer.MAX_VALUE : b[bmid];
if (aval <= bval) {
return kth(a, amid + 1, b, bleft, k - k / 2);
} else {
return kth(a, aleft, b, bmid + 1, k - k / 2);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] A= {1,2,3,4};
int[] B= {2,3,4,5,6,7};
System.out.println(findMedianSortedArrays(A,B));
}
}
第三种解决方法:
class Solution {
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int positionOne = 0, positionTwo = 0, current = 0;
int middleLength = (nums1.length + nums2.length)/2;
int[] results = new int[middleLength+1];
for(int i = 0; current <= middleLength; i++){
if(positionOne < nums1.length && positionTwo < nums2.length){
if(nums1[positionOne] < nums2[positionTwo]){
results[current] = nums1[positionOne];
positionOne++;
current++;
}
else{
results[current] = nums2[positionTwo];
positionTwo++;
current++;
}
}
else if(positionOne < nums1.length){
results[current] = nums1[positionOne];
positionOne++;
current++;
}
else{
results[current] = nums2[positionTwo];
positionTwo++;
current++;
}
}
if(((nums1.length + nums2.length) % 2)==1){
return (double) results[middleLength];
}
return ((double)results[middleLength] + (double)results[middleLength-1])/2;
}
}