有兩個大小爲 m 和 n 的排序數組 nums1 和 nums2 。html
請找出兩個排序數組的中位數而且總的運行時間複雜度爲 O(log (m+n)) 。java
示例1:數組
nums1 = [1, 3]
nums2 = [2]
中位數是 2.0
複製代碼
示例2:bash
nums1 = [1, 2]
nums2 = [3, 4]
中位數是 (2 + 3)/2 = 2.5
複製代碼
歸併&topK問題spa
這個思路就是對於兩個有序數組進行合併,合併到一個大的有序的數組中去,而後求合併後數組的中位數。下面代碼中使用的是歸併排序的方式,對於兩個有序數組進行歸併排序的。從複雜度的角度來講能夠知足題目的要求,可是仍是存在一些問題,主要是怎麼可以使得時間複雜度變成O{MIN(nums1.length,nums2.leng)}。code
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
double result = 0.0d;
int[] nums = new int[nums1.length+nums2.length];
int num1index = 0;
int num2index = 0;
int index = 0;
if (nums1.length == 0 && nums2.length == 0){
return result;
}
if (nums1.length == 0){
return getResult(nums2);
}
if (nums2.length == 0){
return getResult(nums1);
}
while(num1index < nums1.length && num2index < nums2.length){
if (nums1[num1index] < nums2[num2index]){
nums[index]= nums1[num1index];
num1index++;
}else{
nums[index]= nums2[num2index];
num2index++;
}
index++;
}
while (num1index < nums1.length){
nums[index] = nums1[num1index++];
index++;
}
while (num2index < nums2.length){
nums[index] = nums2[num2index++];
index++;
}
if (nums.length%2==0)
{
result = (nums[nums.length/2]+nums[nums.length/2-1])/2.0;
}
else{
result = nums[nums.length/2];
}
return result;
}
private double getResult(int[] nums){
double result = 0.0D;
if (nums.length%2==0)
{
result = (nums[nums.length/2]+nums[nums.length/2-1])/2.0;
}
else{
result = nums[nums.length/2];
}
return result;
}
}
複製代碼
求兩個排序數組的中位數htm
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int size = len1 + len2;
if(size % 2 == 1)
return findKth(nums1, 0, len1, nums2, 0, len2, size / 2 + 1);
else
return (findKth(nums1, 0, len1, nums2, 0, len2, size / 2) + findKth(nums1, 0, len1, nums2, 0, len2, size / 2 + 1)) /2;
}
public double findKth(int[] nums1, int start1, int len1, int[] nums2, int start2, int len2, int k) {
if(len1 - start1 > len2 -start2) // 傳進來的時候統一讓短的數組爲nums1
return findKth(nums2, start2, len2, nums1, start1, len1, k);
if(len1 - start1 == 0) // 表示nums1已經所有加入前K個了,第k個爲nums2[k - 1];
return nums2[k - 1];
if(k == 1)
return Math.min(nums1[start1], nums2[start2]); // k==1表示已經找到第k-1小的數,下一個數爲兩個數組start開始的最小值
int p1 = start1 + Math.min(len1 - start1, k / 2); // p1和p2記錄當前須要比較的那個位
int p2 = start2 + k - p1 + start1;
if(nums1[p1 - 1] < nums2[p2 - 1])
return findKth(nums1, p1, len1, nums2, start2, len2, k - p1 + start1);
else if(nums1[p1 - 1] > nums2[p2 -1])
return findKth(nums1, start1, len1, nums2, p2, len2, k - p2 + start2);
else
return nums1[p1 - 1];
}
}
複製代碼