LeetCode 04 Median of Two Sorted Arrays

題目要求

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)).
??題目翻譯:給定兩個有序數(shù)組nums1和sums2睁本,長度分別是m和n,求出兩個數(shù)組的中間值忠怖,要求算法的復雜度是O(log(m+n))呢堰。

題目分析

該問題可以抽象為一個數(shù)學問題:求第K小的值(或者第K大的值)。假若先合并兩個數(shù)組凡泣,復雜度是O(m+n)枉疼,不符合要求。題目的復雜度要求O(log (m+n))給了我們提示:可以用二分查找來提高查找效率鞋拟。算法設計采用遞歸二分查找骂维,每一次遞歸截斷一半的查找空間。

函數(shù)的偽碼如下findk(int[] a, int m, int[] b, int n, int k)

  1. 假如數(shù)組a長度大于數(shù)組b严卖,交換兩個數(shù)組席舍,保證任何時候,數(shù)組a的長度小于等于數(shù)組b哮笆,簡化條件判斷
  2. 當數(shù)組a空,則返回數(shù)組b的第k個值汰扭,數(shù)組索引是k-1
  3. 當返回第一個最小值的時候(k=1)稠肘,返回數(shù)組a和數(shù)組b最小值中較小的一個
  4. 截斷:pa = Math.min(k/2, m);pb = k - pa萝毛; 可得pa+pb = k项阴,如果a[pa-1] < b[pb-1],顯然可證:a[pa-1]一定小于第k個值,又因為數(shù)組a有序环揽,因此數(shù)組的第0到第pa-1個元素均小于第K個值略荡,可以截斷,同時k = k-pa歉胶,縮小一半的查找空間汛兜。同理可證,a[pa-1] > b[pb-1]時通今,可截斷b[0……pb-1]部分粥谬,k = k-pb

代碼-Java實現(xiàn)

import java.util.*;

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int total = nums1.length + nums2.length;
        /**
         * 假設兩個數(shù)組長度之和是奇數(shù),則中間數(shù)是第 total/2+1 個數(shù)
         * 假設兩個數(shù)組長度之和是奇數(shù)辫塌,則中間數(shù)是第 total/2 個數(shù) 和 第 total/2+1 個數(shù)的平均值
         */
        if (total%2 == 1) {
            return findk(nums1, nums1.length, nums2, nums2.length, total/2+1);
        } else {
            // 為什么傳進去的數(shù)組不會被修改漏策?原因是findk中調(diào)用的是java.util.Arrays.copyOf()實現(xiàn)深拷貝
            // ToDO 偶數(shù)情況的尋找第 total/2+1 個數(shù)字可以在 total/2 上再做一次查找就可以,怎么實現(xiàn)這個優(yōu)化臼氨?
            return (findk(nums1, nums1.length, nums2, nums2.length, total/2) +
                    findk(nums1, nums1.length, nums2, nums2.length, total/2+1)) / 2.0;
        }
    }
    
    // 遞歸查找第K個值
    public double findk(int[] a, int m, int[] b, int n, int k) {
        /**
         * 處理該問題中出現(xiàn)的遞歸的3個邊界條件
         */
        // 保證任何時候掺喻,數(shù)組a的長度小于等于數(shù)組b,簡化條件判斷
        if (m>n)
            return findk(b, n, a, m, k);
        // 當數(shù)組a空储矩,則返回數(shù)組b的第K個值感耙,數(shù)組索引是k-1
        if (m==0)
            return b[k-1];
        // 當返回第一個最小值的時候(k=1),返回數(shù)組a和數(shù)組b最小值中較小的一個
        if (k==1)
            return Math.min(a[0], b[0]);
        
        /**
         * pa+pb = k,如果a[pa-1] < b[pb-1],顯然可證:a[pa-1]一定小于第k個值,
         * 又因為數(shù)組a有序,因此數(shù)組的第0到第pa-1個元素均小于第K個值椰苟,可以截斷抑月,
         * 同時k = k-pa, 縮小一半的查找空間。
         * 
         * 同理可證舆蝴,a[pa-1] > b[pb-1] 時谦絮,可截斷b[0……pb-1]部分,k = k-pb洁仗。
         */
        int pa = 0, pb = 0;
        pa = Math.min(k/2, m); pb = k - pa;
        if (a[pa-1] < b[pb-1]){
            // java.util.Arrays.copyOf()實現(xiàn)深拷貝层皱,內(nèi)部實現(xiàn)是調(diào)用System.arraycopy
            a = Arrays.copyOfRange(a, pa, m);
            return findk(a, m-pa, b, n, k-pa);
        } else if (a[pa-1] > b[pb-1]) {
            // 同上一條注釋
            b = Arrays.copyOfRange(b, pb, n);
            return findk(a, m, b, n-pb, k-pb);
        } else {
            return a[pa-1];
        }
    }
    
    // 測試模塊
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] sum1 = {3,4};
        int[] sum2 = {1,2};
        double result = solution.findMedianSortedArrays(sum1, sum2);
        System.out.println(result);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市赠潦,隨后出現(xiàn)的幾起案子叫胖,更是在濱河造成了極大的恐慌,老刑警劉巖她奥,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓮增,死亡現(xiàn)場離奇詭異,居然都是意外死亡哩俭,警方通過查閱死者的電腦和手機绷跑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凡资,“玉大人砸捏,你說我怎么就攤上這事。” “怎么了垦藏?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵梆暖,是天一觀的道長。 經(jīng)常有香客問我掂骏,道長轰驳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任芭挽,我火速辦了婚禮滑废,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袜爪。我一直安慰自己蠕趁,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布辛馆。 她就那樣靜靜地躺著俺陋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昙篙。 梳的紋絲不亂的頭發(fā)上腊状,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音苔可,去河邊找鬼缴挖。 笑死,一個胖子當著我的面吹牛焚辅,可吹牛的內(nèi)容都是我干的映屋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼同蜻,長吁一口氣:“原來是場噩夢啊……” “哼棚点!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起湾蔓,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘫析,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后默责,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贬循,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年桃序,在試婚紗的時候發(fā)現(xiàn)自己被綠了甘有。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡葡缰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泛释,我是刑警寧澤滤愕,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站洪鸭,受9級特大地震影響忽媒,放射性物質(zhì)發(fā)生泄漏欧募。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一魂贬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧裙顽,春花似錦付燥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至漩怎,卻和暖如春勋颖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勋锤。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工饭玲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叁执。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓茄厘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親徒恋。 傳聞我的和親對象是個殘疾皇子蚕断,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容