タイトル
サイズとnums1 mおよびn nums2二順序付けられた配列を与え。
メジアンおよび整然とした配列の両方を検索し、アルゴリズムの時間複雑度はO(ログ(M + N))である必要があります。
あなたは、空とnums2 nums1の両方を想定することはできません
例
例1
nums1 = [1,3]
nums2 = [2]
中央値は2.0です
例2
nums1 = [1、2]
nums2 = [3、4]
中央値は、(2 + 3)/ 2 = 2.5であります
概念
トピックは中央値を見つけるために、理解することは非常に簡単です、複雑さがどのように(M + N)、O、私はいくつかのプログラミングの経験が行いますがあると信じて、Oの難しさ(ログ(M + N))そう。実際には、この問題は、kの数を計算することです。合計数が偶数のとき、私たちは数とその背後にある数を求めています。私たちは、再帰的に実装されています。再帰関数が小さく、2つの配列Kの位置を比較するために、kの数、各再帰更新kの値(配列が空であることに注意を直接戻すことができる)、各再帰/ 2私たちを見つけるために使用しましたアレイの一部のK / 0~2は、特定の状況の分類コード、1戻るまで再帰的に配列された、廃棄することができる見ることがより直感的であるか、またはkが空です。
コード
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int mid_left = 0;
int mid_right = 0;
//奇偶的情况
mid_left=findk(nums1,nums2,(nums1.length+nums2.length+1)/2);
if((nums1.length+nums2.length)%2==1){
return mid_left;
}
mid_right=findk(nums1, nums2,(nums1.length+nums2.length+2)/2);
return ((double)mid_left+(double)mid_right)/2;
}
//k表示当前寻找第k大的数
public int findk(int[] nums1,int[] nums2,int k){
//nums1为空,直接从nums2中取
if(nums1.length==0) return nums2[k-1];
//nums2为空,直接从nums1中取
if(nums2.length==0) return nums1[k-1];
//第一个元素
if(k==1) return Math.min(nums1[0], nums2[0]);
//drop表示可能丢去的部分
int drop1=Math.min(k/2, nums1.length);
int drop2=Math.min(k/2, nums2.length);
if(nums1[drop1-1]<=nums2[drop2-1]){//丢去nums1的部分
return findk(Arrays.copyOfRange(nums1, drop1, nums1.length), nums2, k-drop1);
}else{
return findk(nums1,Arrays.copyOfRange(nums2,drop2, nums2.length),k-drop2);//丢去nums2的部分
}
}
public static void main(String[] args) {
int a[]={1,3};
int b[]={2,4};
problem4 c=new problem4();
System.out.println(c.findMedianSortedArrays(a, b));
}