合併兩個有序鍊錶

2021-10-09 04:18:38 字數 1898 閱讀 1465

將兩個公升序鍊錶合併為乙個新的公升序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。

示例:

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

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

思路

我們可以如下遞迴地定義兩個煉表裡的merge操作(忽略邊界情況,比如空煉表等):

也就是說,兩個鍊錶頭部值較小的乙個節點與剩下元素的merge操作結果合併。

我們直接將以上遞迴過程建模,同時需要考慮邊界情況。

我們要先判斷給定 兩個鍊錶是否為空鍊錶 ,那麼沒有任何操作需要合併,所以我們只需要返回非空鍊錶。否則,我們要判斷l1l2頭結點哪個更小,然後較小結點的next指標指向其餘結點的合併結果。(呼叫遞迴)如果兩個鍊錶有乙個為空,遞迴結束。

示例**

/**

​ \* definition for singly-linked list.

​ \* struct listnode

​ \*   listnode(int x) : val(x), next(nullptr) {}

​ \*   listnode(int x, listnode *next) : val(x), next(next) {}

​ \* };

​ */

class solution          

else }};

複雜度分析

思路迭代的話,我們要兩個鍊錶中乙個乙個元素拿出來比,所以為了操作方便,我們可以另建鍊錶,然後依次將較小元素追加到新建鍊錶後邊。為了比較完之後知道要將元素插在**,所以要記錄一下最後插入元素的位置。

首先,我們設定乙個哨兵節點 head ,這可以在最後讓我們比較容易地返回合併後的鍊錶。

然後維護乙個 prev 指標,來記錄最後插入元素的位置,方便l1、l2比較完之後快速插入。我們需要做的是調整它的 next 指標。

我們重複以下過程,直到 l1 或者 l2 中沒有元素。如果 l1 當前節點的值小於等於 l2 ,我們就把 l1 當前的節點追加在 prev 節點的後面同時將 l1 指標往後移一位。否則,我們對 l2 做同樣的操作。不管我們將哪乙個元素追加在新鍊錶後面,我們都需要移動 prev 的位置。

在迴圈終止的時候, l1 和 l2 至多有乙個是非空的。由於輸入的兩個鍊錶都是有序的,所以不管哪個鍊錶是非空的,它包含的所有元素都比前面已經合併鍊錶中的所有元素都要大。所以我們只需要將剩下的非空鍊錶追加到新鍊錶後邊,並返回新鍊錶即可。

示例**

/**

* definition for singly-linked list.

* struct listnode

*     listnode(int x) : val(x), next(nullptr) {}

*     listnode(int x, listnode *next) : val(x), next(next) {}

* };

*/class solution          

else

// 插入乙個元素,記錄指標後移

prenode = prenode->next;  

}// 找剩下的非空鍊錶,將其剩餘元素全部追加到新鍊錶中

l1 == nullptr ? prenode->next = l2 : prenode->next = l1;

return head->next;}};

複雜度分析

合併兩個有序鍊錶

鍊錶的題目總是讓我很惆悵。動輒就會runtime error。比如這題,額外用了乙個節點的空間來儲存頭節點。我很不情願多用這個空間,不過貌似不行。貌似不行,實際可行,見附錄。把頭節點提出迴圈 實現類 class solution else if l1 null p next l1 if l2 nul...

合併兩個有序鍊錶

三個指標乙個儲存la鍊錶 乙個儲存lb鍊錶,乙個指向新的鍊錶。鍊錶的插入,兩個指標,乙個是head,乙個指向head後面的鏈,新插入的元素位於head後面。執行該 自己外加上class類。static class node public static void main string args st...

合併兩個有序鍊錶

將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。示例 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4思路 很簡單就是二路歸併的思想,時間複雜度o n definition for singly linked list.struct listno...