Leetcode前端必会系列:合并两个有序链表

70 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

 

示例 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. 动态添加一个空的头结点
  2. 使用两个指针分别指向两个链表的头节点上
  3. 比较两个指针,选择最小的指针进行连接,同时向前前进一位
  4. 最后如果两个指针非空,继续循环添加
  5. 返回头指针的下一个作为结果

解答

 var mergeTwoLists = function(list1, list2) {
  let h = new ListNode()
  let p,q,node
  p = list1,q = list2,node = h
  while(p && q) {
    if(p.val<q.val) {
      node.next = p

      node = p

      p = p.next

    }else if(p.val>q.val) {

      node.next = q

      node = q

      q = q.next

    }else {

      node.next = p

      node = p

      p = p.next

      node.next = q

      node = q

      q = q.next

    }

  }

  while(p) {

    node.next = p

    node = p

    p = p.next

  }

  while(q) {

    node.next = q

    node = q

    q = q.next

  }

  return h.next

};

通过题目的分析,我们利用归并的思想完成了链表的合并,归并的设计十分的简单,就是边遍历边比较。总体的时间复杂度是o(n)

总结

有序链表的合并是十分经典的归并设计思想,通过对归并的理解,我们更加熟悉了其设计过程。