Description

难度简单:剑指 Offer 25. 合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:
0 <= 链表长度 <= 1000

Solution

以 l1 为合并后的链表的开头,依次取 l2 中的一连串处于 l1 中两节点之间的值,合并到 l1 中。以下图为例:
剑指Offer 25. 合并两个排序的链表 - 图1
在 l2 中找到处于 l1 中 1 -> 3 之间的子链表
剑指Offer 25. 合并两个排序的链表 - 图2
将 l2 中 2->3 链接到 l1 中
剑指Offer 25. 合并两个排序的链表 - 图3
重复上述步骤,直到两个链表排序成功
剑指Offer 25. 合并两个排序的链表 - 图4
剑指Offer 25. 合并两个排序的链表 - 图5

  1. class Solution {
  2. public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
  3. if (l1 == null) return l2;
  4. if (l2 == null) return l1;
  5. if (l1.val > l2.val){ // 如果 l2 的 head 结点大于 l1 的 head 结点,交换位置 l1 和 l2
  6. ListNode temp = l1;
  7. l1 = l2;
  8. l2 = temp;
  9. }
  10. // 将 l2 中 start2 到 end2 指向的链表合并到 l1 中 start1 到 start1.next 之间
  11. ListNode start1 = l1;
  12. while(start1.next != null && l2 != null){ // 结束条件
  13. if (start1.next.val < l2.val){ // 跳过 l1 中比 l2 开头小的元素
  14. start1 = start1.next;
  15. continue;
  16. }
  17. ListNode start2 = l2, end2 = l2; // 选取 start2 到 end2 之间的链表
  18. while(end2.next != null && end2.next.val <= start1.next.val)
  19. end2 = end2.next;
  20. // 更新 l2 的指向
  21. l2 = end2.next;
  22. // 将 l2 中 start2 到 end2 链接到 l1 中 start1 到 start1.next 之间
  23. end2.next = start1.next;
  24. start1.next = start2;
  25. // 更新 l1 中 start1 的指向
  26. start1 = end2.next;
  27. }
  28. // 判断 l2 中是否还存有元素
  29. if (l2 != null)
  30. start1.next = l2;
  31. return l1;
  32. }
  33. }

Solution2

用归并排序的思路,解决两个链表合并的问题

  1. class Solution {
  2. public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
  3. ListNode dummyHead = new ListNode(0);
  4. ListNode tail = dummyHead;
  5. while(l1 != null && l2 != null){
  6. if(l1.val <= l2.val){
  7. tail.next = l1;
  8. l1 = l1.next;
  9. }else{
  10. tail.next = l2;
  11. l2 = l2.next;
  12. }
  13. tail = tail.next;
  14. }
  15. if(l1 != null)
  16. tail.next = l1;
  17. if(l2 != null)
  18. tail.next = l2;
  19. return dummyHead.next;
  20. }
  21. }