LeetCode(力扣) 21.合并两个有序链表
文章目录
1.题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例2
输入:l1 = [], l2 = []
输出:[]
示例3
输入:l1 = [], l2 = [0]
输出:[0]
提示:
1.两个链表的节点数目范围是 [0, 50]
2.-100 <= Node.val <= 100
3.l1 和 l2 均按 非递减顺序 排列
2.知识链接
解决本题需要用到链表的知识,先简单复习一下链表的基本使用。
a.创建一个链表(C语言描述)
struct listcode{
int data;//链表中的数据
struct listcode *Next;//指向链表的指针,储存下一个链表的地址
}
注意c语言定义链表还要接着使用 struct listcode;
若typedef struct listcode;
则可以用 listcode 定义链表
b.链表的输入
Node* creatnode()
{
Node *current=NULL,*head=NULL,*last=NULL;
int x;
scanf("%d",&x);
while(x!=-1)
{
current=(Node*)malloc(sizeof(Node));
current->data=x;
if(head==NULL)//当头不存在时,即链表起始为空
{
head=last=current;//连续赋值从左到右;
}
else
{
last->next=current;
last=current;
}
scanf("%d",&x);
}
if(last!=NULL)
last->next=NULL;
return(head);//返回头链表
}
c.摧毁链表
void destory(Node **head)
{
Node *temp,*headptr=(*head);//不能直接释放,否则无法确定下一节点
while(headptr!=NULL)
{
temp=headptr;
headptr=headptr->next;
free(temp);
}
(*head)=NULL;//头指针指向空;
}
d.打印链表
void print(Node *head)
{
Node *temp=head;
while(temp!=NULL)
{
printf("%d%c",temp->data,(temp->nextPtr)?' ':'\n'); //如果节点没有下一的节点,最后一个打印换行,否则打印空格
temp=temp->next;
}
}
3.解题思路
1.迭代法解题:正向思考
先创立一个Pre指针作为头,接着比较l1与l2的数据大小,将Pre指针指向数据较小的呢一个节点,随后Pre指针与该链表后移,重复以上步骤直到其中一个链表到达空;
详细可看官方解答
代码:
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
Node *Prehead;
Node *pre=(struct ListNode*)malloc(sizeof(struct ListNode));
Prehead=pre;
while(l1!=NULL && l2!=NULL)
{
if(l1->val < l2->val)
{
pre->next=l1;
pre=pre->next;
l1=l1->next;
}
else
{
pre->next=l2;
pre=pre->next;
l2=l2->next;
}
}//循环结束有一个链表为空
if(l1==NULL)
pre->next=l2;
else
pre->next=l1;
return(Prehead->next);返回头指向的节点;
}
2.递归法解决:逆向思考
递归的本质是调用自己,所以我们要尝试去从结果入手,反向思考。
题目的要求的函数的作用是将两个链表按从小到大串联起来,我们可以简化为一个数与剩下的两个链表进行串联,即调用自身。
range(list1,list2)=range(newlist1,list2)与较小的第一个数相连;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode* temp;
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
if(l1->val < l2->val)
{
temp=mergeTwoLists(l1->next,l2);
l1->next=temp;
return(l1);//若l1的小,呢么l1为新头,接下来的链表再进行排序;
}
else
{
temp=mergeTwoLists(l1,l2->next);
l2->next=temp;
return(l2);
}
}
总结
该题为链表基础题,用递归的方法解决最为高效,要学会利用函数解决函数,从结果向前思考,将问题进行拆分。