Median of Two Sorted Arrays

標(biāo)簽(空格分隔): C++ 算法 LetCode 數(shù)組

每日算法——letcode系列


問(wèn)題 Median of Two Sorted Arrays

Difficulty: Hard

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)).

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        
    }
};

翻譯

兩個(gè)有序數(shù)組的中位數(shù)

難度系數(shù):困難

有兩個(gè)大小分別為m和n的 nums1nums2有序數(shù)組茂翔。 找出這兩個(gè)有序數(shù)組的中位數(shù)芹缔。 時(shí)間復(fù)雜度應(yīng)為$O(log (m+n))$.

思路

先轉(zhuǎn)化成topK問(wèn)題稻轨,再分兩種情況:

  • m + n為奇數(shù)時(shí),返回第K就好
  • m + n為偶數(shù)時(shí)蛋勺,返回第K和K + 1的平均值

由于題目要求是O(log(m+n))時(shí)間復(fù)雜度逮壁,那必須得用有序的信息,想到二分法付枫,總想把兩數(shù)組各減一半最好,但這種可能把中位數(shù)也剔除了驰怎,
如:
[1, 2, 5, 6] -> [5, 6]
[3, 4, 7, 8] -> [7, 8] 這樣就把中位數(shù)4給剔除了阐滩,但可以得用一點(diǎn),上面?zhèn)€數(shù)組中的[1, 2]是可以剔除的县忌。

兩長(zhǎng)度分別為m, n的數(shù)組A, B掂榔,假設(shè)k = $\frac{(m + n) }{2}$ 继效。
將k分成兩成pa,pb兩部分,由于是兩個(gè)數(shù)組装获,長(zhǎng)度不一致瑞信,為不越界,有兩種分法:(假設(shè)m>n)

  • 當(dāng)$\frac{k}{2}$ $\leq$n時(shí)穴豫, 直接分成pa = pa = $\frac{k}{2}$
  • 當(dāng)$\frac{k}{2}$ > n時(shí), pa = n, pb = k - pa

下面分析當(dāng)$\frac{k}{2}$ $\leq$n的三種情況

  1. A[$\frac{k}{2}$] == B[$\frac{k}{2}$]
  2. A[$\frac{k}{2}$] > B[$\frac{k}{2}$]
  3. A[$\frac{k}{2}$] < B[$\frac{k}{2}$]
  • 第一種情況:
    如果將B合并到A凡简,那么B[0]到B[$\frac{k}{2}$-1]肯定在A的左邊, B[$\frac{k}{2}$+1]到B[n]肯定放在A的右邊精肃,那中位數(shù)即為A[$\frac{k}{2}$]秤涩、B[$\frac{k}{2}$]

  • 第二種情況:
    如果:中位數(shù)在B[0]到B[$\frac{k}{2}$]中, 假設(shè)中位數(shù)的索引為mid肋杖。
    那么B[0] $\leq$B[mid] $\leq$B[$\frac{k}{2}$]溉仑, 則B中至少有n - $\frac{k}{2}$個(gè)在B[mid] 右邊
    由于A[$\frac{k}{2}$] > B[$\frac{k}{2}$]挖函, 則A中至少有m - $\frac{k}{2}$ + 1個(gè)在B[mid] 右邊
    則至少有n - $\frac{k}{2}$ + m - $\frac{k}{2}$ + 1 = k + 1個(gè)數(shù)在B[mid]的右邊, 則當(dāng)且僅當(dāng)mid = $\frac{k}{2}$滿足要求状植, 比如A = [6], B = [1, 2, 8],如果A[$\frac{k}{2}$ -1] > B[$\frac{k}{2}$ -1]呢怨喘?
    同上分析得:則至少有n - ($\frac{k}{2}$ -1) + m - ($\frac{k}{2}$-1) + 1 = k + 3> k+1個(gè)數(shù)在B[mid]的右邊, 則中位數(shù)肯定不在B[0]到B[$\frac{k}{2}$ -1]中津畸,可剔除

  • 第三種情況同第二種類似:當(dāng)A[$\frac{k}{2}$ -1] < B[$\frac{k}{2}$ -1]中位數(shù)肯定不在A[0]到A[$\frac{k}{2}$ -1]中。

由上分析可得:

  1. A[$\frac{k}{2}$-1] == B[$\frac{k}{2}$-1時(shí):A[$\frac{k}{2}$-1]必怜、 B[$\frac{k}{2}$-1]為中位數(shù)
  2. A[$\frac{k}{2}$-1] > B[$\frac{k}{2}$-1]時(shí):中位數(shù)肯定不在B[0]到B[$\frac{k}{2}$-1]中
  3. A[$\frac{k}{2}$-1] < B[$\frac{k}{2}$-1]時(shí):中位數(shù)肯定不在A[0]到A[$\frac{k}{2}$-1]中

則我們可以遞歸的剔除二個(gè)數(shù)組中的一些數(shù)

中止條件:

  • 當(dāng)A[$\frac{k}{2}$-1] == B[$\frac{k}{2}$-1時(shí)肉拓,返回其中一個(gè)
  • 當(dāng)A、B中一個(gè)為空時(shí)梳庆, 分別返回B[k-1]或A[k-1]
  • 當(dāng)k = 1時(shí)暖途, 返回A[0]、B[0]中小的一個(gè)

當(dāng)$\frac{k}{2}$ > n時(shí), 也是同樣的分析方法

代碼


//
//  main.cpp
//  Median of Two Sorted Arrays
//
//  Created by zhz on 15/12/15.
//  Copyright (c) 2015年 zhz. All rights reserved.
//

#include <iostream>
#include <vector>

using namespace std;
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = static_cast<int>(nums1.size());
        int n = static_cast<int>(nums2.size());
        int k = (m + n + 1) / 2;
        
        if ((m + n) % 2 != 0){
            return findKthBigNum(nums1, nums2, k);
        }
        else{
            return  (findKthBigNum(nums1, nums2, k + 1) + findKthBigNum(nums1, nums2, k)) / 2.0;
        }
        
    }
    
private:
    double findKthBigNum(vector<int>& nums1, vector<int>& nums2, int k){
        int m = static_cast<int>(nums1.size());
        int n = static_cast<int>(nums2.size());
        if (n > m){
            return findKthBigNum(nums2, nums1, k);
        }
        if (n == 0){
            return nums1[k - 1];
        }
        if (k == 1){
            
            return nums1[0] < nums2[0] ? nums1[0] : nums2[0];
        }
        
        int pa = min(k / 2, n), pb = k - pa;
        
        if (nums1[pb - 1] == nums2[pa - 1]){
            
            return nums2[pa - 1];
        }
        else if (nums1[pb - 1] > nums2[pa - 1])
        {
            vector<int> tempNums;
            if (pa <= nums2.size()){
                tempNums.assign(nums2.begin() + pa, nums2.end());
                 k = k - pa;
            }
            else{
                k = k - static_cast<int>(nums2.size());
            }
            return findKthBigNum(nums1, tempNums, k);
        }
        else
        {
            vector<int> tempNums;
            if (pb <= nums1.size()){
                tempNums.assign(nums1.begin() + pb, nums1.end());
                k = k - pb;
            }
            else{
                k = k - static_cast<int>(nums1.size());
            }
           
            return findKthBigNum(tempNums, nums2, k);
        }
    }
};
int main(int argc, const char * argv[]) {
    vector<int> nums1 = {3};
    vector<int> nums2 = {1, 2, 4};
    
    auto s = new Solution();
    double mid = s->findMedianSortedArrays(nums1, nums2);
    std::cout << "Hello, World!\n";
    return 0;
}

后記: 代碼的實(shí)現(xiàn)有很多細(xì)節(jié)活膏执,一定要多練驻售,不能光靠想
還有些細(xì)節(jié)沒(méi)完善,比如求平均值最好用位操作更米,不會(huì)越界

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欺栗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子征峦,更是在濱河造成了極大的恐慌迟几,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栏笆,死亡現(xiàn)場(chǎng)離奇詭異类腮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蛉加,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門存哲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)因宇,“玉大人,你說(shuō)我怎么就攤上這事祟偷〔旎” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵修肠,是天一觀的道長(zhǎng)贺辰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嵌施,這世上最難降的妖魔是什么饲化? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮吗伤,結(jié)果婚禮上吃靠,老公的妹妹穿的比我還像新娘。我一直安慰自己足淆,他們只是感情好巢块,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著巧号,像睡著了一般族奢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丹鸿,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天越走,我揣著相機(jī)與錄音,去河邊找鬼靠欢。 笑死廊敌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的门怪。 我是一名探鬼主播骡澈,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼薪缆!你這毒婦竟也來(lái)了秧廉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拣帽,失蹤者是張志新(化名)和其女友劉穎疼电,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體减拭,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔽豺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拧粪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修陡。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沧侥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出魄鸦,到底是詐尸還是另有隱情宴杀,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布拾因,位于F島的核電站旺罢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绢记。R本人自食惡果不足惜扁达,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蠢熄。 院中可真熱鬧跪解,春花似錦、人聲如沸签孔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)骏啰。三九已至节吮,卻和暖如春抽高,著一層夾襖步出監(jiān)牢的瞬間判耕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工翘骂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壁熄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓碳竟,卻偏偏與公主長(zhǎng)得像草丧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莹桅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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