21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)
题目描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按非递减顺序排列
这道链表虽然是简单的,但是涉及链表与递归的应用恰好是我所不熟悉的领域,是一道很不错的练手题目。
本题注意点:
1.对链表的判空仅需分别判断l1、l2是否为空,此两种情况已经包括l1与l2均为空的最终结果,所以无需再判断此情况;
2.将两链表中初始数值小的作为头结点(常识来的);
3.注意递归的使用思想,本题中使用递归,巧妙实现每次比较一个结点的数值;
方法一:递归
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.6 MB, 在所有 Java 提交中击败了90.62%的用户
通过测试用例:208 / 208
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//递归-每次比较一个节点
if(l1==null){
return l2;
}else if(l2==null){
return l1; //l1与l2同时为空的结果已经包含在这两种情况中了
}else if(l1.val<l2.val){
l1.next=mergeTwoLists(l1.next,l2);
return l1; //回传时传的是l1.next,并无赋值,所以最终返回只需返回l1即可
}else{
l2.next=mergeTwoLists(l1,l2.next);
return l2;
}
}
}
有几道很经典的相关题目值得我们练练:
方法二:迭代
我一开始写这道题的时候使用的方式其实就是迭代,但是思路不清晰没能写出来,看完官方解析后重新写了下面这串代码。
注意点:
1.循环条件为:while(l1!=null && l2!=null),意味着最后返回前需判空,因为迭代完成后至多剩下一个非空链表,此时只需将非空链表直接连接到prev指针所指的下一个即可;
2.每次找到一个结点,只需完成将该节点赋值到prev结点之后、将被赋值结点链表指针指向其下一个结点与下文所提及的第三点注意点共三步即可;
3.prehead是一个新建的结点,用于记录排序后链表的起始点;而prev用于构建排序链表,所以每次找到一个结点后,prev都需要将自己赋值为其下一个结点,以便继续连接 。
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.9 MB, 在所有 Java 提交中击败了25.32%的用户
通过测试用例:208 / 208
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//迭代
ListNode prehead=new ListNode(-1); //新建一个链表结点,用于记录头节点的位置
ListNode prev=prehead; //用于移动的结点
while(l1!=null && l2!=null){
if(l1.val<l2.val){
prev.next=l1;
l1=l1.next;
}else{
prev.next=l2;
l2=l2.next;
}
prev=prev.next;
}
//合并结束后俩链表至少有一个非空,我们只需要把非空的那个直接连接在排序完的链表之后即可
prev.next= l1==null ? l2:l1;//由于循环条件为while(l1!=null && l2!=null)
return prehead.next;
}
}
平平无奇小白程序媛一枚,欢迎各位大佬交流指教,如有不正确的地方,欢迎留言改正,谢谢!!!