目录
题目描述:
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:0 <= 链表长度 <= 1000
思路1
新定义一个链表,然后分别从l1和l2中取较小的数插入新链表中。空间复杂度,时间复杂度
思路2(迭代)
新定义一个节点node,然后分别比较l1和l2的当前节点val大小,如果l1 < l2,则把node.next = l1,l1指向下一个节点,否则把node.next = l2,l2指向下一个节点,然后直到l1和l2都为空之前,不断循环以上过程。代码如下:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
function ListNode(val){
this.val = val
this.next = null
}
var mergeTwoLists = function (l1, l2) {
if (!l1 && !l2) return null
let cur = new ListNode()
const head = cur
while(l1 || l2){
if(!l1){
cur.next = l2 //***
return head.next
}else if(!l2){
cur.next = l1 //***
return head.next
}
if(l1.val <= l2.val){
cur.next = l1 //***
l1 = l1.next
}else {
cur.next = l2 //***
l2 = l2.next
}
cur = cur.next
}
return head.next //###
}
let l1 = new ListNode(1)
l1.next = new ListNode(2)
l1.next.next = new ListNode(3)
let l2 = new ListNode(1)
l2.next = new ListNode(3)
l2.next.next = new ListNode(4)
console.log(mergeTwoLists(l1, l2))
注意!!这里我踩了一个坑,记录下来以免日后忘记
假设现在有一个链表LinkList(1->2->3),有以下代码
var cur = new ListNode() const head = cur cur = LinkList console.log(head.next.val)
这里的head.next.val会输出什么?一开始我认为,应该是2。因为head指向cur,cur又指向了LinkList首节点,cur.next节点是2,那么head.next节点也应该是2.这是错的!!事实上,这里会输出undefined。为什么呢?
我们来分析一下这段代码的前三句话
1.定义一个有ListNode里属性的cur节点,为它分配空间,作图如下:
2.定义一个常量head,把cur里存放的堆区的地址给它
3.cur指向LinkList节点,即cur里存放LinkList堆区地址
坑出现了!!可以由图中看到,head仍旧指向原来没有被赋值的空间,而cur指向了新的空间。所以head.next会等于null,此时head与cur不再相等了。如果我们还想让head与cur指向同一个空间,并且head也能取到LinkList里的值该怎么办呢?
很简单,让cur.next 指向LinkLisk节点!
如果我们把上面第3行cur = LinkList 改为cur.next = LinkList,那么此时堆和栈是什么样的?
要想获取0x456里的val,只要用head.next就好了
综上所述,这就是为什么在迭代代码里***处,要用cur.next去存l1,并且在最后的时候也返回的是head.next
迭代法时间复杂度 ,空间复杂度
思路3(递归)
把问题细分,考虑两个链表合并,可以转换为两个链表的子链表合并。如果l1.val < l2.val,说明l1当前节点可以被保留,接下来要合并的两个链表就是l1.next和l2,临界条件是l1为空(l1已经遍历完)或l2为空(l2已经遍历完)。以此写出递归方法。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function (l1, l2) {//递归
if(!l1) return l2
if(!l2) return l1
while(l1 || l2){
if(l1.val < l2.val){
l1.next = mergeTwoLists(l1.next, l2)
return l1
}else{
l2.next = mergeTwoLists(l1, l2.next)
return l2
}
}
}
递归法时间复杂度,空间复杂度