题目描述
这是一道难度为简单的题目,同时,这道题也是Leetcode148题中,链表归并排序中重要的组成部分。
题目描述
题目分析
本题的题目简单易懂,输入为两个有序链表,要求将链表合并为一个有序的链表。在此不在再赘述。
解题思路一
先分享一下最容易想到的思路。
新建一个链表newHead,不断的比较输入的两个有序链表中的最小值,不断以最小值建立新结点,插入到新链表newHead上。
该方法的时间复杂度是O(m+n),其中m、n分别为输入的两个链表的长度。
该方法的空间复杂度是O(m+n),需要重建m+n个链表节点。
解题思路二
上述思路也可以通过递归来实现。
从两个输入链表的头结点l1、l2开始进行比较,将结点值较小者设为头结点,递归调用自身计算l1.next和l2(或l1和l2.next)的合并,使头节点指向合并后的链表头。
后续的函数继续递归调用。
该方法的时间复杂度是O(m+n),其中m、n分别为输入的两个链表的长度。
该方法的空间复杂度是O(m+n),最差需要m+n个递归栈。
思路二示例代码
以下是小王同学对思路二的Java实现,供各位读者参考。
思路二示例代码
解题思路三
那有没有空间复杂度为O(1),时间复杂度为O(m+n)的方法呢?
答案当然是有。
该方法和思路一很相似,只不过不新建链表结点,而是把输入的两个结点串起来。
具体是怎么操作呢?
首先设置一个pre指针,指向一个新建的结点,它是我们找到输出结果的关键。
接下来设立一个end指针,指向我们结果链表(pre)的最后一个元素,用来从两条输入链表中串联新的元素。
然后,遍历两个链表,每次找到较小的结点,将该结点插入结果链表(pre),插入的方法是把结点接到end指针后面。
完成上述工作后,需要更新输入链表的头指针和end指针,一切就大功告成啦。
思路三示例代码
以下是小王同学对思路三的Java实现,供各位读者参考。
思路三示例代码
总结
这是一道简单的链表相关的题目,但是对面试者基本功的要求还是很高,面试的时候一般是需要写出最优解的。
对于非递归解法,难点在于指针的设置和更新,这也是链表问题中常见的问题,需要我们重视。