代码随想录算法训练营|day3

第二章 链表

  • 203. 移除链表元素
  • 707. 设计链表
  • 206. 反转链表
  • 总结

203. 移除链表元素

题目链接
文章详解

 type ListNode struct {
    Val int
    Next *ListNode
}

(1)直接删除

func removeElements(head *ListNode, val int) *ListNode {
    // 删除头节点
    cur := &ListNode{}
    for head != nil && head.Val == val {
        cur = head
        head = head.Next
    }
    // 删除非头节点
    cur = head
    for cur != nil && cur.Next != nil {
        if cur.Next.Val == val {
            cur.Next = cur.Next.Next
        }else {
            cur = cur.Next
        }
    }
    return head
}

(2)创建虚拟头指针,方便删除。判断指针不为空

func removeElements(head *ListNode, val int) *ListNode {
    dummyHead := &ListNode{}
    dummyHead.Next = head
    cur := dummyHead
    for cur != nil && cur.Next != nil {
        if cur.Next.Val == val {
            cur.Next = cur.Next.Next
        }else {
            cur = cur.Next
        }
    }
    return dummyHead.Next
}

(3)递归法
首先删除head之外的节点,之后判断head节点是否要被删除;
递归终止条件:head是否为空。若为空直接返回head,否则递归删除

func removeElements(head *ListNode, val int) *ListNode {
    if head == nil {
        return head
    }
    head.Next = removeElements(head.Next, val)
    if head.Val == val {
        return head.Next
    }
    return head
}

707. 设计链表

题目链接
文章详解
添加、删除节点注意链表长度;找前驱节点;注意边界范围

type MyLinkedList struct {
    head *ListNode
    size int
}

func Constructor() MyLinkedList {
    return MyLinkedList{&ListNode{}, 0}
}

func (this *MyLinkedList) Get(index int) int {
    if index < 0 || index >= this.size {
        return -1
    }
    cur := this.head
    for i := 0; i <= index; i++ {
        cur = cur.Next
    }
    return cur.Val
}

func (this *MyLinkedList) AddAtHead(val int)  {
    this.AddAtIndex(0, val)
}

func (this *MyLinkedList) AddAtTail(val int)  {
    this.AddAtIndex(this.size, val)
}

func (this *MyLinkedList) AddAtIndex(index int, val int)  {
    if index > this.size {
        return
    }
    index = max(index, 0)
    this.size++
    pre := this.head
    for i := 0; i < index; i++ {
        pre = pre.Next
    }
    pre.Next = &ListNode{val, pre.Next}
}

func (this *MyLinkedList) DeleteAtIndex(index int)  {
    if index < 0 || index >= this.size {
        return
    }
    this.size--
    pre := this.head
    for i := 0; i < index; i++ {
        pre = pre.Next
    }
    pre.Next = pre.Next.Next
}

206. 反转链表

题目链接
文章详解
(1)迭代法
顺序转圈的操作:保存(next)、反转(prev)、移动

func reverseList(head *ListNode) *ListNode {
    var prev *ListNode
    cur := head
    for cur != nil {
        next := cur.Next
        cur.Next = prev
        prev = cur
        cur = next
    }
    return prev
}

(2)递归法

func reverseList(head *ListNode) *ListNode {
    return reverse(nil, head)
} 

func reverse(prev, head *ListNode) *ListNode {
    if head == nil {
        return prev
    }
    next := head.Next
    head.Next = prev
    return reverse(head, next) 
}

总结

递归法没太理解,这两天再看看。学习参考

你可能感兴趣的:(代码随想录练习,go,算法)