【剑指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 };
View Code

栈,虽然空间复杂度>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 };
View Code

 递归,最精妙

 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 };
View Code

 

posted @ 2022-11-09 16:57  啊原来是这样呀  阅读(26)  评论(0编辑  收藏  举报