【剑指offer】4.合并两个排序的链表
总目录:
1.问题描述
输入两个递增的链表,单个链表的长度为n(两链表长度不一定相等),合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围: 0≤n≤1000,−1000≤节点值≤1000
要求:空间复杂度 O(1),时间复杂度 O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6};
或输入{-1,2,4},{1,3,4}时,合并后的链表为{-1,1,2,3,4,4},所以对应的输出为{-1,1,2,3,4,4}。
2.问题分析
两链表长度不一定相等,注意当一个已经为空另一个不为空时的处理方法;
可采取的方法:
1暴力迭代,逐个识别大小添加到新链表中,注意维护2个输入链表的指针;
2栈,先压栈再弹栈;
3递归,调用递归时注意输入元素的选择,颇有田忌赛马的感觉;
3.代码实例
暴力迭代
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { 12 13 ListNode* newHead = new ListNode(1);//创建头节点 14 ListNode* curNode = newHead; 15 16 while (pHead1 != NULL && pHead2 != NULL) { 17 if (pHead1->val >= pHead2->val) { 18 curNode->next = pHead2; 19 pHead2 = pHead2->next; 20 } else { 21 curNode->next = pHead1; 22 pHead1 = pHead1->next; 23 } 24 curNode = curNode->next; 25 } 26 27 if (pHead1 != NULL) { 28 curNode->next = pHead1; 29 } 30 if (pHead2 != NULL) { 31 curNode->next = pHead2; 32 } 33 34 curNode = newHead->next; //取有有效数据的第一个节点 35 delete newHead;//释放无数据的头节点 36 return curNode; 37 } 38 };
栈,虽然空间复杂度>O(1)
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { 12 13 ListNode* newHead = NULL; 14 ListNode* tempP = NULL; 15 stack<ListNode*> sp; 16 17 //压栈,有序化 18 while (pHead1 != NULL || pHead2 != NULL) { 19 if (pHead1 == NULL) { 20 sp.push(pHead2); 21 pHead2 = pHead2->next; 22 continue; 23 } 24 if (pHead2 == NULL) { 25 sp.push(pHead1); 26 pHead1 = pHead1->next; 27 continue; 28 } 29 30 //比较二者大小 31 if (pHead1->val >= pHead2->val) { 32 sp.push(pHead2); 33 pHead2 = pHead2->next; 34 } else { 35 sp.push(pHead1); 36 pHead1 = pHead1->next; 37 } 38 } 39 40 //弹栈 41 while (!sp.empty()) { 42 tempP = sp.top(); 43 sp.pop(); 44 45 tempP->next = newHead; 46 newHead = tempP; 47 } 48 49 50 return newHead; 51 } 52 };
递归,最精妙
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { 12 //递归中止条件 13 if (pHead1 == NULL || pHead2 == NULL) { 14 return pHead1 == NULL ? pHead2 : pHead1; 15 } 16 17 //调用递归,两个元素依次对比 18 if(pHead1->val>pHead2->val) 19 { 20 pHead2->next=Merge(pHead1,pHead2->next); 21 return pHead2; 22 } 23 else 24 { 25 pHead1->next=Merge(pHead1->next,pHead2); 26 return pHead1; 27 } 28 } 29 };