4.ルック中央leetcodeタイトル2つの命じた配列

タイトル

サイズと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));
	}

結果

ここに画像を挿入説明

公開された15元の記事 ウォンの賞賛0 ビュー191

おすすめ

転載: blog.csdn.net/qq_36360463/article/details/103963707