链表算法题

一、反转链表

力扣地址指针

实现方法一:三指针遍历,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
}

二、删除链表的节点

力扣地址code

解法:增长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
}

三、合并两个有序单向链表

力扣地址递归

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
}
相关文章
相关标签/搜索