LeetCode :21.合并兩個有序鏈表

1.題目

將兩個有序鏈表合并為一個新的有序鏈表并返回和二。新鏈表是通過拼接給定的兩個鏈表的所有節(jié)點組成的。

2.示例

輸入:

1->2->4, 1->3->4

輸出:

1->1->2->3->4->4

3.解法探析

3.1 解法 1:迭代法

3.1.1 解題思路

1.對于空鏈表耳胎,假如鏈表 l1為空則返回鏈表 l2惯吕,鏈表 l2為空則返回鏈表 l1惕它。
2.比較鏈表 l1鏈表 l2的第一個結點的值,將值小的結點保存下來作為合并后新鏈表的第一個結點废登,并把值小的結點的鏈表向后移動一位淹魄。
3.不斷在兩個鏈表剩下的結點中選擇較小的值,鏈接到新鏈表的后面堡距,直至某一個鏈表為空甲锡。
4.當兩個鏈表長度不同時,會有一個鏈表先為空羽戒,此時把另外一個鏈表剩下的結點都連接到新鏈表的末尾缤沦。

3.1.2 代碼實現

C++實現:

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        } else if (l2 == nullptr) {
            return l1;
        }

        // 申請dummy指針作為一個虛擬的頭結點,并將其成員初始化為 -1
        ListNode* dummy = new ListNode(-1);                 
        ListNode* cur = dummy;

        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val < l2->val) {
                cur->next = l1;
                l1 = l1->next;
            } else {
                cur->next = l2;
                l2 = l2->next;
            }

            cur = cur->next;
        }

        if (l1 == nullptr) {
            cur->next = l2;
        } else if (l2 == nullptr) {
            cur->next = l1;
        }

        return dummy->next;
    }
};

GO實現:

type ListNode struct {
    Val int
    Next *ListNode
}

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    // 如果有一個鏈表為 nil易稠,直接返回另一個鏈表
    if l1 == nil {
        return l2
    } else if l2 == nil {
        return l1
    }

    // 定義一個臨時的頭指針缸废,它的 Next 指向的結點才有數據
    dummy := &ListNode{}
    cur := dummy

    for l1 != nil && l2 != nil {
        if l1.Val < l2.Val {
            cur.Next = l1
            // cur 與 l1 都往后移動一位
            // 相當于 l1 = l1.Next cur = cur.Next
            cur, l1 = cur.Next, l1.Next
        } else {
            cur.Next = l2
            cur, l2 = cur.Next, l2.Next
        }
    }

    // 循環(huán)完之后,把鏈表剩下的結點直接放到后面驶社,因為鏈表本身就是有序的企量,所以鏈接在后面就行
    if l1 == nil {
        cur.Next = l2
    } else if l2 == nil {
        cur.Next = l1
    }

    return dummy.Next
}

3.1.3 復雜度分析

時間復雜度:O(n + m)(假設 n 為鏈表1的長度,m 為鏈表2的長度)
空間復雜度:O(1)

3.2 解法 2:遞歸法

3.2.1 解題思路

1.對于空鏈表亡电,假如鏈表 l1為空則返回鏈表 l2届巩,鏈表 l2為空則返回鏈表 l1
2.比較兩個鏈表中第一個結點的大小份乒,確定頭結點的位置恕汇。
3.頭結點確定后,繼續(xù)在兩個鏈表剩下的結點中選出較小的結點鏈接到第 2 步選出的結點后面冒嫡,然后再繼續(xù)重復 第 2拇勃、3 步,直到有鏈表為空孝凌。

3.2.2 代碼實現

C++實現:

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        } else if (l2 == nullptr) {
            return l1;
        }

        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);

            return l1;
        } else {
            l2->next = mergeTwoLists(l2->next, l1);

            return l2;
        }
    }
};

GO實現:

type ListNode struct {
    Val int
    Next *ListNode
}

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    // 如果有一個鏈表為 nil方咆,直接返回另一個鏈表
    if l1 == nil {
        return l2
    } else if l2 == nil {
        return l1
    }

    // 對ListNode類型進行一次 new 的實例化操作,也可以使用 dummy := new(ListNode) 進行實例化
    dummy := &ListNode{}

    // 獲取結構體實例的指針
    newHead := dummy

    if l1.Val < l2.Val {
        newHead = l1
        newHead.Next = mergeTwoLists(l1.Next, l2)
    } else {
        newHead = l2
        newHead.Next = mergeTwoLists(l2.Next, l1)
    }

    return newHead
}

3.2.3 復雜度分析

時間復雜度:O(n + m)(假設 n 為鏈表1的長度蟀架,m 為鏈表2的長度)
空間復雜度:O(n + m)


個人主頁:

www.codeapes.cn

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末瓣赂,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子片拍,更是在濱河造成了極大的恐慌煌集,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捌省,死亡現場離奇詭異苫纤,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門卷拘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喊废,“玉大人,你說我怎么就攤上這事栗弟∥劭辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵乍赫,是天一觀的道長瓣蛀。 經常有香客問我,道長雷厂,這世上最難降的妖魔是什么惋增? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮改鲫,結果婚禮上器腋,老公的妹妹穿的比我還像新娘。我一直安慰自己钩杰,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布诊县。 她就那樣靜靜地躺著讲弄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪依痊。 梳的紋絲不亂的頭發(fā)上避除,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音胸嘁,去河邊找鬼瓶摆。 笑死,一個胖子當著我的面吹牛性宏,可吹牛的內容都是我干的群井。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼毫胜,長吁一口氣:“原來是場噩夢啊……” “哼书斜!你這毒婦竟也來了?” 一聲冷哼從身側響起酵使,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤荐吉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后口渔,有當地人在樹林里發(fā)現了一具尸體样屠,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了痪欲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悦穿。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖勤揩,靈堂內的尸體忽然破棺而出咧党,到底是詐尸還是另有隱情,我是刑警寧澤陨亡,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布傍衡,位于F島的核電站,受9級特大地震影響负蠕,放射性物質發(fā)生泄漏蛙埂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一遮糖、第九天 我趴在偏房一處隱蔽的房頂上張望绣的。 院中可真熱鬧,春花似錦欲账、人聲如沸屡江。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惩嘉。三九已至,卻和暖如春踢故,著一層夾襖步出監(jiān)牢的瞬間文黎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工殿较, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留耸峭,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓淋纲,卻偏偏與公主長得像劳闹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洽瞬,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容