LeetCode--004--尋找兩個有序數組的中位數(java)


 

 

其中,N1=4,N2=6,size=4+6=10.

1,現在有的是兩個已經排好序的數組,結果是要找出這兩個數組中間的數值,如果兩個數組的元素個數為偶數,則輸出的是中間兩個元素的平均值。
2,可以想象,如果將數組1隨便切一刀(如在3和5之間切一刀),數組1將分成兩份,數組1左別的元素的個數為1,右邊的元素的個數為3。

由於數組1和數組2最終分成的左右兩份的個數是確定的,都是所有元素的個數的一半(size/2=5)所以我們也可以知道,此時對數組2應該切的一刀的位置應該在10和11之間,數組2左邊的個數為4,右邊的個數為2.才能使兩個數組左右兩邊的元素個數加起來的和(1+4=2+3)相等。
另外,我們記在數組1靠近這一刀的左別的元素為L1(3),右邊元素為R1(5).同理,記在數組2靠近這一刀的左別的元素為L2(10),右邊元素為R2(11).
如果這一刀的位置是正確的,則應該有的結果是
L1<=R2
L2<=R1
這樣就能確保,左邊的元素都小於右邊的元素了。

3,所以,我們只需要直接找出在數組1切這一刀的正確位置就可以了。
為了減少查找次數,我們對短的數組進行二分查找。將在數組1切割的位置記為cut1,在數組2切割的位置記為cut2,cut2=(size/2)-cut1。
cut1,cut2分別表示的是數組1,數組2左邊的元素的個數。
4,切這一刀的結果有三種
1)L1>R2  則cut1應該向左移,才能使數組1較多的數被分配到右邊。
2)L2>R1 則cut1應該向右移,才能使數組1較多的數被分配到左邊。
3)其他情況(L1<=R2  L2<=R1),cut1的位置是正確的,可以停止查找,輸出結果。
5,其他說明
1)考慮到邊界條件,就是cut的位置可能在邊緣,就是cut1=0或者cut1=N1,cut2=0或者cut2=N2的這些情況,我們將min和max兩個特殊值分別加在數組1和數組2的兩端,就可以統一考慮了。還有N1個數為0的時候,直接輸出結果即可。
2)為了減少查找時間,使用的是二分查找,就是cut1的位置是一半一半的查找的,實現時間只要log(N),不然就會超時。所以,我們不能只是簡單地將cut1–或者cut1++,而是要記下每次cut1的區域范圍,我們將cut1的范圍記錄下來,用[cutL,cutR]表示。一開始cut1的范圍是[cutL,cutR]=[0,N1],
如果L1>R2  則cut1應該向左移,才能使數組1較多的數被分配到右邊。cut1的范圍就變成了[cutL,cut1-1],下次的cut1的位置就是cut1 = (cutR - cutL) / 2 + cutL;。
如果L2>R1 則cut1應該向右移,才能使數組1較多的數被分配到左邊。cut1的范圍就變成了[cut1+1,cutR],下次的cut1的位置就是cut1 = (cutR - cutL) / 2 + cutL;。
3)數組的元素個數和是奇數的情況下,中間的元素應該就是min(R1,R2),只需另外處理輸出就可以了。

time log(min(m,n))

space o(1)

 1 class Solution {
 2     public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
 3         if(nums1.length > nums2.length){
 4             return findMedianSortedArrays(nums2, nums1);
 5         }
 6         int len = nums1.length + nums2.length;
 7         int cut1 = 0;
 8         int cut2 = 0;
 9         int cutL = 0;
10         int cutR = nums1.length;
11         while(cut1 <= nums1.length){
12             cut1 = (cutR - cutL)/2 + cutL;
13             cut2 = len/2 - cut1;
14             double L1 = (cut1 == 0 )? Integer.MIN_VALUE:nums1[cut1 - 1];
15             double L2 = (cut2 == 0 )? Integer.MIN_VALUE:nums2[cut2 - 1];
16             double R1 = (cut1 == nums1.length )? Integer.MAX_VALUE:nums1[cut1];
17             double R2 = (cut2 == nums2.length )? Integer.MAX_VALUE:nums2[cut2];
18             if(L1>R2){
19                 cutR = cut1 - 1;
20             }else if(L2 > R1){
21                 cutL = cut1 + 1;
22             }else{
23                 if(len %2 == 0){
24                     L1 = (L1 > L2) ? L1 : L2;
25                     R1 = (R1 > R2 )? R2 : R1;
26                     return (L1+R1)/2;
27                 }else{
28                     R1 = (R1 < R2) ? R1 : R2;
29                     return R1;
30                 }
31             }
32         } 
33     return -1;
34     }
35    
36 }

轉自https://blog.csdn.net/chen_xinjia/article/details/69258706

 2019-03-11 23:06:05


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM