本文首發於公衆號「五分鐘學算法」,是圖解 LeetCode 系列文章之一。c++
我的網站:www.cxyxiaowu.comgit
題目來源於 LeetCode 上第 21 號問題:合併兩個有序鏈表。題目難度爲 Easy,目前經過率爲 45.8% 。github
將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是經過拼接給定的兩個鏈表的全部節點組成的。算法
示例:bash
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
複製代碼
(1)對空鏈表存在的狀況進行處理,假如 pHead1 爲空則返回 pHead2 ,pHead2 爲空則返回 pHead1。(兩個都爲空此狀況在pHead1爲空已經被攔截) (2)在兩個鏈表無空鏈表的狀況下肯定第一個結點,比較鏈表1和鏈表2的第一個結點的值,將值小的結點保存下來爲合併後的第一個結點。而且把第一個結點爲最小的鏈表向後移動一個元素。 (3)繼續在剩下的元素中選擇小的值,鏈接到第一個結點後面,並不斷next將值小的結點鏈接到第一個結點後面,直到某一個鏈表爲空。 (4)當兩個鏈表長度不一致時,也就是比較完成後其中一個鏈表爲空,此時須要把另一個鏈表剩下的元素都鏈接到第一個結點的後面。網站
ListNode* mergeTwoOrderedLists(ListNode* pHead1, ListNode* pHead2){
ListNode* pTail = NULL;//指向新鏈表的最後一個結點 pTail->next去鏈接
ListNode* newHead = NULL;//指向合併後鏈表第一個結點
if (NULL == pHead1){
return pHead2;
}else if(NULL == pHead2){
return pHead1;
}else{
//肯定頭指針
if ( pHead1->data < pHead2->data){
newHead = pHead1;
pHead1 = pHead1->next;//指向鏈表的第二個結點
}else{
newHead = pHead2;
pHead2 = pHead2->next;
}
pTail = newHead;//指向第一個結點
while ( pHead1 && pHead2) {
if ( pHead1->data <= pHead2->data ){
pTail->next = pHead1;
pHead1 = pHead1->next;
}else {
pTail->next = pHead2;
pHead2 = pHead2->next;
}
pTail = pTail->next;
}
if(NULL == pHead1){
pTail->next = pHead2;
}else if(NULL == pHead2){
pTail->next = pHead1;
}
return newHead;
}
複製代碼
(1)對空鏈表存在的狀況進行處理,假如 pHead1 爲空則返回 pHead2 ,pHead2 爲空則返回 pHead1。 (2)比較兩個鏈表第一個結點的大小,肯定頭結點的位置 (3)頭結點肯定後,繼續在剩下的結點中選出下一個結點去連接到第二步選出的結點後面,而後在繼續重複(2 )(3) 步,直到有鏈表爲空。spa
ListNode* mergeTwoOrderedLists(ListNode* pHead1, ListNode* pHead2){
ListNode* newHead = NULL;
if (NULL == pHead1){
return pHead2;
}else if(NULL ==pHead2){
return pHead1;
}else{
if (pHead1->data < pHead2->data){
newHead = pHead1;
newHead->next = mergeTwoOrderedLists(pHead1->next, pHead2);
}else{
newHead = pHead2;
newHead->next = mergeTwoOrderedLists(pHead1, pHead2->next);
}
return newHead;
}
}
複製代碼