[leetcode題解]Median of Two Sorted Arrays

4. Median of Two Sorted Arrays

題目

https://leetcode.com/problems/median-of-two-sorted-arrays/description/

題意是給出兩個(gè)有序的列表猴蹂,找出它們合并之后的中位數(shù)(如果個(gè)數(shù)為偶數(shù)渡嚣,則是兩個(gè)中位數(shù)的平均數(shù))。

時(shí)間復(fù)雜度要求是O(log(m+n))

解題思路

由于這題有時(shí)間復(fù)雜度要求,可以發(fā)現(xiàn)將兩個(gè)列表合并成新列表再使用二分查找是不可行的袁辈。(時(shí)間復(fù)雜度為O(m+n)

所以這題我也是看了題解才有了思路妙黍。

由于兩個(gè)列表 各自是有序的碾篡,我們可以考慮通過(guò)切割列表來(lái)尋找中位數(shù)砍的。考慮同時(shí)切割列表氨肌,一個(gè)切割點(diǎn)為i鸿秆,一個(gè)切割點(diǎn)為j,切割會(huì)把 列表分為[0, i), [i, n) ,[0, j), [j, m) 四個(gè)子列表怎囚,如果能滿(mǎn)足以下條件卿叽,則我們可以快速找到中位數(shù):

1)i+j = (m+n)/2

2)a[i-1] <= b[j]

3)b[j-1] <= a[i]

這樣我們可以快速找到中位數(shù)為:

奇數(shù)情況下為:

min(a[i], b[j])

偶數(shù)情況下為:

(min(a[i], b[j]) + max(a[i-1], b[j - 1]))/2

示例代碼

 class Solution {
public:
    int min(int a, int b){
        return a < b ? a: b;
    }
    int max(int a, int b){
        return a > b ? a: b;
    }
    int minelement(int indexa, int indexb, vector<int>& nums1 , vector<int>& nums2){
        if(indexa == nums1.size()){
            return nums2[indexb];
        }
        if(indexb == nums2.size()){
            return nums1[indexa];
        }
        return min(nums1[indexa], nums2[indexb]);
    }
    
    int maxelement(int indexa, int indexb, vector<int>& nums1 , vector<int>& nums2){
        if(indexa == nums1.size()){
            return nums2[indexb];
        }
        if(indexb == nums2.size()){
            return nums1[indexa];
        }
        return max(nums1[indexa], nums2[indexb]);
    }
    
int next(int temp, int tl, int tr){
    if(tl +1 == tr ){
        if(temp == tl){
            return tr;
        }else{
            return tl;
        }
    }
    return (tl + tr) /2;
}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int l1 = nums1.size();
        int l2 = nums2.size();
        int l = l1 + l2;
        int mid = l / 2;
        int temp, temp2 = 0;
        if(l1 < l2){
            nums1.swap(nums2);
            l1 = nums1.size();
            l2 = nums2.size();
        }
        if(l2 == 0){
            if(l1 % 2 == 0){
                return (double) (nums1[l1 / 2] + nums1[l1 / 2 - 1]) /2;
            }else{
                return (double) nums1[l1 / 2];
            }
        }
        int tl = 0, tr = l1;
        temp = (tl + tr) / 2;
        while(true){
            temp2 = mid - temp;
            if(temp > mid){ 
                tr = temp;
                temp = next(temp, tl, tr);
                continue;
            }
            if(temp2 > l2){
                tl = temp;
                temp = next(temp, tl, tr);
                continue;
            }
            if(temp2 == 0){
                if(nums1[temp - 1] <= nums2[0]){
                    break;
                }else{
                    tr = temp;
                    temp = next(temp, tl, tr);
                    continue;
                }
            }else if(temp2 == l2){
                if(nums2[temp2 - 1] <= nums1[temp]){
                    break;
                }else{
                    tl = temp;
                    temp = next(temp, tl, tr);
                    continue;
                }
            }else{
                if(nums1[temp - 1] <= nums2[temp2] && nums2[temp2 - 1] <= nums1[temp]){
                    break;
                }else if(nums1[temp - 1] > nums2[temp2]){
                    tr = temp;
                    temp = next(temp, tl, tr);
                    continue;
                }else{
                    tl = temp;
                    temp = next(temp, tl, tr);
                    continue;
                }
            }
            
        }
        
        if( l % 2 == 0){
            int s;
            if(temp2 == 0){
                s = nums1[temp - 1] + minelement(temp, 0, nums1, nums2);
            }else if(temp2 == l2){
                s = maxelement(temp - 1, l2 - 1, nums1, nums2) + nums1[temp];
            }else{
                s = maxelement(temp - 1, temp2 - 1, nums1, nums2) + minelement(temp, temp2, nums1, nums2);
            }
            return (double)s / 2;
        }else{
            if(temp2 == 0){
                 return (double) minelement(temp,0, nums1, nums2);
            }else if(temp2 == l2){
                return (double) nums1[temp];
            }else{
                return (double) minelement(temp, temp2, nums1, nums2);
            }
        }
    }
}; 

注意細(xì)節(jié)

  1. 注意i和j為0或者列表長(zhǎng)度的時(shí)候(這里的corner case很多)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恳守,隨后出現(xiàn)的幾起案子考婴,更是在濱河造成了極大的恐慌,老刑警劉巖催烘,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沥阱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伊群,警方通過(guò)查閱死者的電腦和手機(jī)考杉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)在岂,“玉大人奔则,你說(shuō)我怎么就攤上這事”挝纾” “怎么了易茬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)及老。 經(jīng)常有香客問(wèn)我抽莱,道長(zhǎng),這世上最難降的妖魔是什么骄恶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任食铐,我火速辦了婚禮,結(jié)果婚禮上僧鲁,老公的妹妹穿的比我還像新娘虐呻。我一直安慰自己,他們只是感情好寞秃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布斟叼。 她就那樣靜靜地躺著,像睡著了一般春寿。 火紅的嫁衣襯著肌膚如雪朗涩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天绑改,我揣著相機(jī)與錄音谢床,去河邊找鬼兄一。 笑死,一個(gè)胖子當(dāng)著我的面吹牛识腿,可吹牛的內(nèi)容都是我干的出革。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼渡讼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蹋盆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起硝全,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎楞抡,沒(méi)想到半個(gè)月后伟众,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡召廷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年凳厢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竞慢。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡先紫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出筹煮,到底是詐尸還是另有隱情遮精,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布败潦,位于F島的核電站本冲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏劫扒。R本人自食惡果不足惜檬洞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沟饥。 院中可真熱鬧添怔,春花似錦、人聲如沸贤旷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)遮晚。三九已至性昭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間县遣,已是汗流浹背糜颠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工汹族, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人其兴。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓顶瞒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親元旬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子榴徐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,724評(píng)論 0 33
  • Description: There are two sorted arrays nums1 and nums2 ...
    CharlieGuo閱讀 412評(píng)論 0 0
  • Description There are two sorted arrays nums1 and nums2 o...
    Omega_Ariston閱讀 316評(píng)論 0 1
  • 還有什么壞事不能發(fā)生在我身上匀归,一定是不能沒(méi)有了坑资,難受的迷糊了過(guò)去。清醒的時(shí)候竟然是在醫(yī)院都能發(fā)生穆端,整個(gè)人都太累了袱贮,...
    Holidayq閱讀 148評(píng)論 1 0
  • 心理學(xué)偏差之確認(rèn)偏差,人送外號(hào)偏差之父体啰!~\(≧≦)/~啦啦啦我們來(lái)看看這是在心理學(xué)效應(yīng)里面多么牛的一個(gè)角色攒巍! 先...
    HincL閱讀 1,203評(píng)論 0 0