(LeetCode篇)6. 合併兩個有序鏈表

題目描述:

將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 

示例:

輸入:1->2->4, 1->3->4

輸出:1->1->2->3->4->4

 

分析:

思路:

我們可以用迭代的方法來實現上述算法。我們假設 l1 元素嚴格比 l2元素少,我們可以將 l2 中的元素逐一插入 l1 中正確的位置。

 

算法:

首先,我們設定一個哨兵節點 "prehead" ,這可以在最後讓我們比較容易地返回合併後的鏈表。我們維護一個 prev 指針,我們需要做的是調整它的 next 指針。然後,我們重複以下過程,直到 l1 或者 l2 指向了 null :如果 l1 當前位置的值小於等於 l2 ,我們就把 l1 的值接在 prev 節點的後面同時將 l1 指針往後移一個。否則,我們對 l2 做同樣的操作。不管我們將哪一個元素接在了後面,我們都把 prev 向後移一個元素。

 

在循環終止的時候, l1 和 l2 至多有一個是非空的。由於輸入的兩個鏈表都是有序的,所以不管哪個鏈表是非空的,它包含的所有元素都比前面已經合併鏈表中的所有元素都要大。這意味着我們只需要簡單地將非空鏈表接在合併鏈表的後面,並返回合併鏈表。

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {     
        //創建一個‘哨兵’節點
        ListNode* preHead = new ListNode(-1);
        //創建一個鏈表節點,並指向哨兵節點
        ListNode* pNode = preHead;
        
        //如果兩個鏈表節點 l1, l2 不爲空
        while(l1 != nullptr && l2 != nullptr)
        {
            //判斷當前兩個節點指針指向的節點的值的大小
            if(l1->val < l2->val)
            {
                //將 pNode 指向鏈表 l1
                pNode->next = l1;
                //將 l1 向後移動
                l1 = l1->next;
            }
            else
            {
                //將 pNode 指向鏈表 l2
                pNode->next = l2;
                //將 l2 向後移動
                l2 = l2->next;
            }
            //將 pNode 往後移動
            pNode = pNode->next;
        }
        //判斷 pNode-> next是否爲空
        //如果 l1 爲空,則返回 l2
        //如果 l2 爲空,則返回 l1
        pNode->next = l1 == nullptr? l2 : l1;
        
        //聲明一個臨時變量
        ListNode* temp = preHead->next;
        delete preHead;
        //返回最終的結果
        return temp;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章