1. 程式人生 > >leetcode 21. 合併兩個有序連結串列 C++版

leetcode 21. 合併兩個有序連結串列 C++版

將兩個有序連結串列合併為一個新的有序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。 

示例:

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

分析:

  首先我想到的是l2插入到l1裡面,並且使用前插法,使用前插法就需要一個頭節點,我命名為Boss,boss->next = l1 進行連結,p指標指向待比較節點父節點,q指向待比較節點,接著迴圈判斷比較l2->val和q->val的大小,如果q->val <= l2->val ,則將l2節點插入到l1裡面,一直迴圈,知道出現一方為空。

  判空有兩種情形,一種是l2先到達空節點,那麼就說明l2的所有資料都成功插入,就直接退出迴圈並返回。

  第二種是l1先到達空節點,這就說明l2中還有資料,而且l2中的資料全部大於l1當前所有的資料,那麼就只需要將l2連結進l1即可。

改進:

  基本和上述相同,只不過用兩個指標mn,m指向第一個小於p->val的值,n指向第一個大於q->val的值,插入時就插入m到n這一段,就減少了插入次數。我這裡實現的是非改進版。。。。

  持續改進ing。。。。。

/**
 * 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 *boss = new ListNode(0);
        if(NULL == l2 || NULL == l1)
            return NULL == l1?l2:l1;
        if(l2->val < l1->val)
            boss->val = l2->val;
        else
            boss->val = l1->val;
        boss->next = l1;
        //p指向待比較節點的父節點,q指向待比較節點
        ListNode *p,*q;
        p = boss;
        q = boss->next;
        while(NULL != l2){
            if(l2->val <= q->val){
                //插到前面
                p->next = l2;
                p = p->next;
                l2 = l2->next;
                p->next  = q;
                //注意,到了這裡是不能將p,q指標往後移動的,要是實在不懂就畫個圖就一目瞭然了。
            }else{
                p = q;
                q = q->next;
            }
            if(NULL == q){
                //注意,這裡不能使用q = l2,這樣會造成q與p斷鏈
                p->next = l2;
                break;
            }
        }
        return boss->next;
    }
};