题目

合并两个有序链表 - 图1

解题思路

当 l1 和 l2 都不是空链表时,判断 l1 和 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。

首先设定一个哨兵节点 prehead ,可以在最后比较容易地返回合并后的链表。维护一个 prev 指针,每次调整它的 next 指针。

然后,重复以下过程,直到 l1 或者 l2 指向了 null :如果 l1 当前节点的值小于等于 l2 ,我们就把 l1 当前的节点接在 prev 节点的后面同时将 l1 指针往后移一位。否则,我们对 l2 做同样的操作。不管我们将哪一个元素接在了后面,我们都需要把 prev 向后移一位。

在循环终止的时候, l1 和 l2 最多有一个是非空的。由于输入的两个链表都是有序的,所以不管哪个链表是非空的,它包含的所有元素都比前面已经合并链表中的所有元素都要大。这意味着只需要简单地将非空链表接在合并链表的后面,并返回合并链表即可。

代码

  1. class Solution {
  2. public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
  3. ListNode prehead = new ListNode(-1);
  4. ListNode prev = prehead;
  5. while (l1 != null && l2 != null) {
  6. if (l1.val <= l2.val) {
  7. prev.next = l1;
  8. l1 = l1.next;
  9. } else {
  10. prev.next = l2;
  11. l2 = l2.next;
  12. }
  13. prev = prev.next;
  14. }
  15. // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
  16. prev.next = l1 == null ? l2 : l1;
  17. return prehead.next;
  18. }
  19. }