21. Merge Two Sorted Lists
递归
不需要dummy head, 因为可以确定是返回哪个头节点
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 ==nil{
return l2
}
if l2 == nil{
return l1
}
// 1-3 2-4
var head *ListNode
if l1.Val < l2.Val{
head = l1
// in 1(head) (3 2-4)
newHead := mergeTwoLists(l1.Next,l2)
// out sub 1 (2-3-4)
// sub to father 1->(2-3-4)
head.Next = newHead
}else{
head = l2
newHead := mergeTwoLists(l1,l2.Next)
head.Next = newHead
}
return head
}
https://leetcode-cn.com/submissions/detail/57614448/
迭代
Q: 为什么迭代解法需要用dummy
A: 如果不用dummy,那么往新链表添加节点就用2种情况: 空链表添加节点 和 非空链表添加节点,这就产生了2套添加逻辑,所以可以通过添加dummy统一为非空链表添加节点。
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy // x(cur,dummy) // cur:在循环过程中,cur指向新链表的尾节点
for l1!=nil && l2!=nil { // 1-nil 2-nil
if l1.Val < l2.Val{
cur.Next = l1 // x-1
l1 = l1.Next
}else{
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next // x-1(cur)
}
if l1 !=nil{
cur.Next = l1
}
if l2 !=nil{
cur.Next = l2
}
return dummy.Next
}
- 规律总结
总结删除链表节点和合并有序链表的迭代解法,可以得出以下规律:
链表题目中, 删除节点和添加节点 各自都会面临2种处理逻辑删除节点(头节点,中间节点) 添加节点(空链表,非空链表)
, 此时可以用dummy head统一为一种处理逻辑。
进一步提炼共同点, 似乎就是当不能确定要返回的链表头节点是哪个时,可能就需要dummy节点。 // 参考附录1视频
- [参考合并有序链表,使用迭代解法, 如何想到要引入dummy head](https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/javashi-pin-jiang-jie-xi-lie-merge-two-sorted-list/ 1分50秒)