連結串列 21.合併兩個有序連結串列
阿新 • • 發佈:2020-08-05
題目
將兩個升序連結串列合併為一個新的升序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
思路
第一個思路就是以迭代的方式,逐一比較連結串列元素大小關係,改變指標的指向,最後整合成一條有序的連結串列,這個思路比較簡單。另外一個思路需要理解理解,用遞迴的方式。在寫程式碼前,先想一想遞迴的公式。
result = L1+mergeTwoLists(L1->next,L2) L1->val < L2->val
result = L2+mergeTwoLists(L1,L2->next) 其他(L1->val >= L2->val)
當L1的元素小於L2的元素時,合併的新連結串列 = L1當前節點 + L1剩餘連結串列與L2連結串列的合併。反之則是,合併的新連結串列 = L2當前節點 + L2剩餘連結串列與L1連結串列的合併。
因為合併的過程存在重複的操作,所以才使用遞迴。
遞迴出口為
if(!L1) { return L2; } if(!L2) { return L1; }
即當L1為空,則合併連結串列為L2,當L2為空,則合併連結串列為L1。
程式碼實現
/**
*迭代
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(!l1)
{
return l2;
}
if(!l2)
{
return l1;
}
struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *p = head;
while( l1 != NULL && l2 != NULL )
{
if( l1->val < l2->val )
{
p->next = l1;
l1 = l1->next;
}
else
{
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
/*
*接上已經有序的部分連結串列
*/
if (l1) p->next = l1;
else if (l2) p->next = l2;
return head->next;
}
/**
*遞迴
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(!l1)
{
return l2;
}
if(!l2)
{
return l1;
}
if( l1->val < l2->val )
{
l1->next = mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next = mergeTwoLists(l1,l2->next);
return l2;
}
}