21. 合并兩個(gè)有序鏈表

將兩個(gè)升序鏈表合并為一個(gè)新的 升序 鏈表并返回诸蚕。新鏈表是通過拼接給定的兩個(gè)鏈表的所有節(jié)點(diǎn)組成的踪宠。

示例
輸入:l1 = [1,2,4], l2 = [1,3,4]
輸出:[1,1,2,3,4,4]
示例 2:

輸入:l1 = [], l2 = []
輸出:[]
示例 3:

輸入:l1 = [], l2 = [0]
輸出:[0]
 

提示:

兩個(gè)鏈表的節(jié)點(diǎn)數(shù)目范圍是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非遞減順序 排列

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/merge-two-sorted-lists
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有自赔。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處柳琢。

方法一:遞歸

思路

我們可以如下遞歸地定義兩個(gè)鏈表里的 merge 操作(忽略邊界情況绍妨,比如空鏈表等):

也就是說,兩個(gè)鏈表頭部值較小的一個(gè)節(jié)點(diǎn)與剩下元素的 merge 操作結(jié)果合并柬脸。

算法

我們直接將以上遞歸過程建模他去,同時(shí)需要考慮邊界情況。

如果 l1 或者 l2 一開始就是空鏈表 倒堕,那么沒有任何操作需要合并灾测,所以我們只需要返回非空鏈表。否則垦巴,我們要判斷 l1 和 l2 哪一個(gè)鏈表的頭節(jié)點(diǎn)的值更小媳搪,然后遞歸地決定下一個(gè)添加到結(jié)果里的節(jié)點(diǎn)铭段。如果兩個(gè)鏈表有一個(gè)為空,遞歸結(jié)束蛾号。


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        } else if (l2 == null) {
            return l1;
        } else if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

作者:LeetCode-Solution
鏈接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
來源:力扣(LeetCode)
著作權(quán)歸作者所有稠项。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處鲜结。

方法二:迭代

思路

我們可以用迭代的方法來實(shí)現(xiàn)上述算法。當(dāng) l1 和 l2 都不是空鏈表時(shí)活逆,判斷 l1 和 l2 哪一個(gè)鏈表的頭節(jié)點(diǎn)的值更小精刷,將較小值的節(jié)點(diǎn)添加到結(jié)果里,當(dāng)一個(gè)節(jié)點(diǎn)被添加到結(jié)果里之后蔗候,將對(duì)應(yīng)鏈表中的節(jié)點(diǎn)向后移一位怒允。

算法

首先,我們?cè)O(shè)定一個(gè)哨兵節(jié)點(diǎn) prehead 锈遥,這可以在最后讓我們比較容易地返回合并后的鏈表纫事。我們維護(hù)一個(gè) prev 指針,我們需要做的是調(diào)整它的 next 指針所灸。然后丽惶,我們重復(fù)以下過程,直到 l1 或者 l2 指向了 null :如果 l1 當(dāng)前節(jié)點(diǎn)的值小于等于 l2 爬立,我們就把 l1 當(dāng)前的節(jié)點(diǎn)接在 prev 節(jié)點(diǎn)的后面同時(shí)將 l1 指針往后移一位钾唬。否則,我們對(duì) l2 做同樣的操作侠驯。不管我們將哪一個(gè)元素接在了后面抡秆,我們都需要把 prev 向后移一位。

在循環(huán)終止的時(shí)候吟策, l1 和 l2 至多有一個(gè)是非空的儒士。由于輸入的兩個(gè)鏈表都是有序的,所以不管哪個(gè)鏈表是非空的檩坚,它包含的所有元素都比前面已經(jīng)合并鏈表中的所有元素都要大着撩。這意味著我們只需要簡(jiǎn)單地將非空鏈表接在合并鏈表的后面,并返回合并鏈表即可效床。

下圖展示了 1->4->5 和 1->2->3->6 兩個(gè)鏈表迭代合并的過程:


示例
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode prehead = new ListNode(-1);

        ListNode prev = prehead;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                prev.next = l1;
                l1 = l1.next;
            } else {
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }

        // 合并后 l1 和 l2 最多只有一個(gè)還未被合并完睹酌,我們直接將鏈表末尾指向未合并完的鏈表即可
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
    }
}

作者:LeetCode-Solution
鏈接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
來源:力扣(LeetCode)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)剩檀,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處憋沿。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沪猴,隨后出現(xiàn)的幾起案子辐啄,更是在濱河造成了極大的恐慌采章,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壶辜,死亡現(xiàn)場(chǎng)離奇詭異悯舟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)砸民,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門抵怎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岭参,你說我怎么就攤上這事反惕。” “怎么了演侯?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵姿染,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我秒际,道長(zhǎng)悬赏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任娄徊,我火速辦了婚禮闽颇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嵌莉。我一直安慰自己进萄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布锐峭。 她就那樣靜靜地躺著中鼠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沿癞。 梳的紋絲不亂的頭發(fā)上援雇,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音椎扬,去河邊找鬼惫搏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蚕涤,可吹牛的內(nèi)容都是我干的筐赔。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼揖铜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼茴丰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤贿肩,失蹤者是張志新(化名)和其女友劉穎峦椰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汰规,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汤功,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溜哮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滔金。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茂嗓,靈堂內(nèi)的尸體忽然破棺而出鹦蠕,到底是詐尸還是另有隱情,我是刑警寧澤在抛,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站萧恕,受9級(jí)特大地震影響刚梭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜票唆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一朴读、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧走趋,春花似錦衅金、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姨伟,卻和暖如春惩琉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夺荒。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工瞒渠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人技扼。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓伍玖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親剿吻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子窍箍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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