算法训练第三天|203.移除链表元素|707.设计链表|206.反转链表

LeetCode 203.移除链表元素

题目链接:203.移除链表元素

题目讲解:代码随想录

题目描述:给你一个链表的头节点 head 和一个整数 val,请你删除链表中所有满足 Node.val == val的节点,并返回新的头节点 。

推荐使用虚拟头结点,这样在移除节点时,代码写起来比较统一。如果不使用虚拟头结点,则第一个节点的移除和其他节点的移除,代码写起来不一致,需要单独考虑。

整体思路:

  1. 先定义虚拟头结点,将虚拟节点的Next指向链表。
  2. 定位到Node.val == val的节点(一般是使用游标cur,cur.Next.Val == val,这样后续处理起来方便)。
  3. 找到,进行cur.Next = cur.Next操作。找不到,进行cur = cur.Next操作。
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
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
}

 LeetCode 707.设计链表

题目链接:707.设计链表

题目讲解:代码随想录

这道题考察的都是一些基础,比如:链表结构体的定义、结构体的实例化、如何移动指针、索引条件的判断、链表节点增删。

go语言中结构体的实例化有两种方式:

// 定义单链表
type SingleNode struct{
    Val int
    Next *SingleNode
}

func main(){
    val := 123

    // 第一种实例化方法
    node := &SingleNode{Val:val} // 可以直接在里面进行初始化
    
    // 第二种实例化方法
    node2 := new(SingleNode)
    SingleNode.Val = val
}

题目如下: 

// 定义单链表
type SingleNode struct{
    Val int
    Next *SingleNode
}

type MyLinkedList struct {
    dummyHead *SingleNode // 虚拟头节点
    Size int
}

// 构造函数
func Constructor() MyLinkedList {
    newNode := &SingleNode{
        -999,
        nil,
    }
    return MyLinkedList{
        dummyHead: newNode,
        Size:0,
    }
}

// 获取指定位置节点的值
func (this *MyLinkedList) Get(index int) int {
    if this == nil || index < 0 || index >= this.Size{ // 如果索引无效则直接返回
        return -1
    }

    cur := this.dummyHead.Next
    for i := 0; i < index; i++{ // 遍历到对应位置的节点
        cur = cur.Next
    }
    return cur.Val
}

// 在队头增加节点
func (this *MyLinkedList) AddAtHead(val int)  {
    newNode := &SingleNode{Val:val}
    newNode.Next = this.dummyHead.Next
    this.dummyHead.Next = newNode
    this.Size++
}

// 在队尾增加节点
func (this *MyLinkedList) AddAtTail(val int)  {
    newNode := new(SingleNode)
    newNode.Val = val
    cur := this.dummyHead
    for cur.Next != nil{ // 遍历至队尾
        cur = cur.Next
    }
    cur.Next = newNode
    this.Size++
}

// 在指定位置增加节点
func (this *MyLinkedList) AddAtIndex(index int, val int)  {
    if index < 0 {
        index = 0
    }else if index > this.Size{
        return
    }

    newNode := &SingleNode{Val:val}
    cur := this.dummyHead
    for i := 0; i < index; i++{ // 遍历到对应位置的节点
        cur = cur.Next
    }
    newNode.Next = cur.Next
    cur.Next = newNode
    this.Size++
}

// 删除节点
func (this *MyLinkedList) DeleteAtIndex(index int)  {
    if index < 0 || index >= this.Size { // 如果索引无效则直接返回
		return
	}
	cur := this.dummyHead        // 设置当前节点为虚拟头节点
	for i := 0; i < index; i++ { // 遍历到要删除节点的前一个节点
		cur = cur.Next
	}
	if cur.Next != nil {
		cur.Next = cur.Next.Next // 当前节点直接指向下下个节点,即删除了下一个节点
	}
	this.Size-- // 注意删除节点后应将链表大小减一
}

LeetCode 206.反转链表 

题目链接:206.反转链表

题目讲解:代码随想录

题目描述:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

 思路:

  1. 定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
  2. 开始反转了,首先要把 cur->next 节点用tmp指针保存一下,用于找回原始链表(因为接下来要改变 cur->next 的指向)。
  3. cur->next 的指向pre,实现了第一个节点的翻转,然后pre指向cur,同时cur指针指向temp,找到原始链表。
  4. 循环这个过程,最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
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
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值