题目介绍
力扣21题:leetcode-cn.com/problems/me…
分析
给你输入两个有序链表,请你把他俩合并成一个新的有序链表,函数签名如下:
ListNode mergeTwoLists(ListNode l1, ListNode l2);
这题比较简单,我们直接看解法:
/**
* 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 dummy = new ListNode(-1);
ListNode p = dummy;
ListNode p1 = l1, p2 = l2;
while(p1 != null && p2 != null) {
// 比较 p1 和 p2 两个指针
// 将值较小的的节点接到 p 指针
if(p1.val < p2.val) {
p.next = p1;
p1 = p1.next;
}else {
p.next = p2;
p2 = p2.next;
}
// p 指针不断前进
p = p.next;
}
//如果l1还没有遍历完,直接拼接到p指针后面
if(p1 != null) {
p.next = p1;
}
//如果l2还没有遍历完,直接拼接到p指针后面
if(p2 != null) {
p.next = p2;
}
return dummy.next;
}
}
我们的 while 循环每次比较p1
和p2
的大小,把较小的节点接到结果链表上:
这个算法的逻辑类似于「拉拉链」,l1, l2
类似于拉链两侧的锯齿,指针p
就好像拉链的拉索,将两个有序链表合并。
代码中还用到一个链表的算法题中是很常见的「虚拟头节点」技巧,也就是dummy
节点。你可以试试,如果不使用dummy
虚拟节点,代码会复杂很多,而有了dummy
节点这个占位符,可以避免处理空指针的情况,降低代码的复杂性。