链表算法题
1、反转链表
实现方法一:三指针遍历,pre+cur+next;时间复杂度O(n),空间复杂度O(1)。
func reverseList(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
实现方法二:递归解法,1+ (reverse(2,3));时间复杂度O(n),空间复杂度O(n)(递归调用要占用系统栈空间)。
func reverseList(head *ListNode) *ListNode {
//1.递归结束
if head == nil || head.Next == nil{
return head
}
//2.递归主体
newHead := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return newHead
}
2、删除链表的节点
解法:增加dummyHead,把删除头尾节点的特殊情况,变成了普通情况。
func removeElements(head *ListNode, val int) *ListNode {
dummyHead := &ListNode{}
dummyHead.Next = head
cur := dummyHead
for cur.Next != nil{
if cur.Next.Val == val{
cur.Next = cur.Next.Next
}else{
cur = cur.Next
}
}
return dummyHead.Next
}
3、合并两个有序单向链表
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
dummyHead := &ListNode{}
cur := dummyHead
for l1 != nil && l2 != nil{
if l1.Val <= l2.Val{
cur.Next = l1
cur = l1
l1 = l1.Next
}else{
cur.Next = l2
cur = l2
l2 = l2.Next
}
}
cur.Next = l1
if l1 == nil {
cur.Next = l2
}
return dummyHead.Next
}
悟以往之不谏,知来者之可追!