[Go] LeetCode第三天|203.移除链表元素 707.设计链表 206.反转链表

203.移除链表元素

题目链接: https://leetcode.cn/problems/remove-linked-list-elements/
关键词:单链表

解法

/**
 * 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   //此处不能为head,因为当所有的结点都要移除时,只会修改dummuHead.Next,head和之后结点并未受影响
}

707.设计链表

题目链接: https://leetcode.cn/problems/design-linked-list/
关键词:链表

解法

注意:题目的下标 index 和数组一样,从0开始

type MyLinkedList struct {
	dummyHead *SingleNode
	Size      int
}

type SingleNode struct {
	Val  int
	Next *SingleNode
}

func Constructor() MyLinkedList {
	//初始化哑结点
	newNode := &SingleNode{
		Val:  -1,
		Next: nil,
	}
	return MyLinkedList{
		dummyHead: newNode,
		Size:      0,
	}
}

func (this *MyLinkedList) Get(index int) int {
	//判断是否非法
	if index < 0 || index >= this.Size {    //注意此处为>=
		return -1
	}
	//获取头结点
	cur := this.dummyHead.Next
	for i := 0; i < index; i++ {    //循环index次
		cur = cur.Next
	}
	return cur.Val
}

func (this *MyLinkedList) AddAtHead(val int) {
	newNode := &SingleNode{
		Val:  val,
		Next: this.dummyHead.Next,
	}
	this.dummyHead.Next = newNode
	this.Size++
}

func (this *MyLinkedList) AddAtTail(val int) {
	newNode := &SingleNode{
		Val: val,
	}
	tail := this.dummyHead
	for tail.Next != nil {
		tail = tail.Next
	}
	tail.Next = newNode
	this.Size++
}

func (this *MyLinkedList) AddAtIndex(index int, val int) {
	newNode := &SingleNode{
		Val: val,
	}
	if index < this.Size {
		cur := this.dummyHead //设置当前节点为虚拟头节点
		for i := 0; i < index; i++ {
			cur = cur.Next // 遍历至index的前一个节点
		}
		newNode.Next = cur.Next
		cur.Next = newNode
		this.Size++
	} else if index == this.Size {
		cur := this.dummyHead
		for i := 0; i < index; i++ {
			cur = cur.Next
		}
		cur.Next = newNode
		this.Size++
	}
}

func (this *MyLinkedList) DeleteAtIndex(index int) {
	if index < 0 || index >= this.Size {
		return
	}
	pre := this.dummyHead
	for ; index > 0; index-- { //会循环index次。从哑结点(可以看作index=-1)开始走,即走到会走到下标为index-1的结点
		pre = pre.Next
	}
	t := pre.Next
	pre.Next = t.Next
	t.Next = nil
	this.Size--
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Get(index);
 * obj.AddAtHead(val);
 * obj.AddAtTail(val);
 * obj.AddAtIndex(index,val);
 * obj.DeleteAtIndex(index);
 */

206.反转链表

题目链接: https://leetcode.cn/problems/reverse-linked-list/
关键词:单链表

解法一:新建List

相当于头插法,新建List浪费了空间

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseList(head *ListNode) *ListNode {
    dummyHead := &ListNode{
        Next: head,
    }
    newListNode := &ListNode{
        Next: nil,
    }
    for dummyHead.Next != nil{
        cur := dummyHead.Next
        dummyHead.Next = dummyHead.Next.Next  //这行代码与下行代码一定不能颠倒顺序
        cur.Next = newListNode.Next
        newListNode.Next = cur
    }
    return newListNode.Next
}

解法二:双指针 1.0

直接将相邻之间的结点指向反向,无需额外开辟空间

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseList(head *ListNode) *ListNode {
	if head == nil {
		return nil
	}
	if head.Next == nil {
		return head
	}
	pre := head
	cur := head.Next
	temp := &ListNode{}
	for cur.Next != nil {
		temp = cur.Next
		cur.Next = pre
		pre = cur
		cur = temp
	}
	cur.Next = pre
	head.Next = nil
	return cur
}

解法三:双指针 2.0

将 pre 设置为指向 *ListNode 类型的空指针,相当于虚拟头结点的作用,统一操作

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseList(head *ListNode) *ListNode {
    var pre *ListNode = nil
    cur := head
    for cur != nil {
        temp := cur.Next
        cur.Next = pre
        pre = cur
        cur = temp
    }
    return pre
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值