Golang leetcode707 设计链表 (链表大成)

2024-01-02 06:28

本文主要是介绍Golang leetcode707 设计链表 (链表大成),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 设计链表 Leetcode707
    • 不使用头节点
    • 使用头节点 推荐**

设计链表 Leetcode707

题目要求我们通过实现几个方法来完成对链表的各个操作
由于在go语言中都为值传递,(注意这里与值类型、引用类型的而区别),所以即使我们直接在方法中传入指针,但是我们在方法里是不能直接修改指针所改的地址,其在方法中只会复制一份副本进行操作,而不会影响到原变量。
所以我们这里可以设置一个结构体,在mylinkedlist中在定义链表节点进行解决。
关于值传递的注意事项

这里放一个经典的愚蠢案例以作警戒,妄想通过副本直接影响原链表
我是猪

func (this *MyLinkedList) AddAtTail(val int) {Node := this.Headif Node == nil {Node = &ListNode{Val: val}//this.Head = Nodereturn}for Node.Next != nil {Node = Node.Next}Node.Next = &ListNode{Val: val}
}

不使用头节点

// ListNode 定义链表结构
type ListNode struct {Val  intNext *ListNode
}//正常建立,不涉及头节点
// MyLinkedList 为了方便操作链表建立的结构体
type MyLinkedList struct {size intHead *ListNode
}// Constructor 初始化链表对象 √
func Constructor() MyLinkedList {return MyLinkedList{}
}// Get 获取第index个节点的数据 √
func (this *MyLinkedList) Get(index int) int {if index+1 > this.size {return -1}Node := this.Headfor ; index > 0; index-- {Node = Node.Next}return Node.Val
}// AddAtHead 将数据为val的节点添加到第一位 √
func (this *MyLinkedList) AddAtHead(val int) {Node := &ListNode{Val: val, Next: this.Head}this.Head = Nodethis.size++
}// AddAtTail 将数据为val的节点添加到最后一位 √
func (this *MyLinkedList) AddAtTail(val int) {this.size++if this.Head == nil {this.Head = &ListNode{Val: val}return}Node := this.Headfor Node.Next != nil {Node = Node.Next}Node.Next = &ListNode{Val: val}
}// AddAtIndex 将数据为val的节点插入到第index个节点之前;若链表长度为index,则放置到最后一位;若超过链表长度不做修改 √
func (this *MyLinkedList) AddAtIndex(index int, val int) {if this.size == index {this.AddAtTail(val)return}if this.size < index {return}//有第index节点//如果index=0,则需要改动首结点,直接待用addAtHeadif index == 0 {this.AddAtHead(val)return}cur := this.HeadNode := cur//0 1 2 3	;index=2for ; index > 1; index-- {Node = Node.Next}Node.Next = &ListNode{Val: val, Next: Node.Next}this.Head = curthis.size++
}// DeleteAtIndex 删除第index个节点
func (this *MyLinkedList) DeleteAtIndex(index int) {if index+1 > this.size {return}// 0 1 2 3	;index=0//如果index=0,依旧需要修改头节点if index == 0 {this.Head = this.Head.Nextthis.size--return}Node := this.Headcur := Node0 1 2 3	;index=3,删除最后一个,只需要将最后.next=nil//if index+1 == this.size {//	for ; index > 1; index-- {//		cur = cur.Next//	}//	cur.Next = nil//	this.Head = Node//	this.size--//	return//}//0 1 2 3	;index=2//for ; index > 1; index-- {//	cur = cur.Next//}//cur.Next = cur.Next.Next//this.Head = Node//this.size--for ; index > 1; index-- {cur = cur.Next}if index+1 == this.size {cur.Next = nilthis.size--return}cur.Next = cur.Next.Nextthis.Head = Nodethis.size--
}

使用头节点 推荐**

首先性能足够优秀,而且代码简洁还方便
在这里插入图片描述

//本次目标时建立具有 头节点 的链表(虚拟头节点,但实际就是有头节点)
//链表结构:H* 0 1 2 3
//优势,在对头节点后的节点进行操作会方便type MyLinkedList struct {Size      intDummyHead *ListNode
}// Constructor 使用虚拟头节点时,很关键的一步在在初始化我们的mylinkedlist,我们需要直接对dummyhead分配内存空间,防止后续对首个节点进行操作时出现问题
func Constructor() MyLinkedList {return MyLinkedList{DummyHead: &ListNode{}}
}func (this *MyLinkedList) Get(index int) int {//*h 0 1 2 3	;0if this.Size <= index {return -1}DummyHead := this.DummyHeadcur := DummyHeadfor ; index >= 0; index-- {cur = cur.Next}return cur.Val
}func (this *MyLinkedList) AddAtHead(val int) {//if this.Size == 0 {//	this.Head = &ListNode{Next: &ListNode{Val: val}}//	this.Size++//} else {//	this.Head.Next = &ListNode{Val: val, Next: this.Head.Next}//	this.Size++//}//newNode := &ListNode{Val: val} // 创建新节点//newNode.Next = this.Head.Next  // 新节点指向当前头节点//this.Head.Next = newNode       // 新节点变为头节点//this.Size++                    // 链表大小增加1//上面第一块没想明白,逻辑有问题;第二部分进行整合,本质一样this.DummyHead.Next = &ListNode{Val: val, Next: this.DummyHead.Next}this.Size++
}func (this *MyLinkedList) AddAtTail(val int) {if this.Size == 0 {this.AddAtHead(val)return}DummyHead := this.DummyHeadcur := DummyHead//h* 0 1 2 3 4	;for cur.Next != nil {cur = cur.Next}cur.Next = &ListNode{Val: val}this.DummyHead = DummyHeadthis.Size++
}func (this *MyLinkedList) AddAtIndex(index int, val int) {//如果index=链表长度,插入到末尾if this.Size == index {this.AddAtTail(val)return}//如果index>链表长度,什么都不做//<长度,插入到index节点前//h* 0 1 2 3 4	;2if this.Size > index {DummyHead := this.DummyHeadcur := DummyHeadfor ; index > 0; index-- {cur = cur.Next}cur.Next = &ListNode{Val: val, Next: cur.Next}this.DummyHead = DummyHeadthis.Size++}}func (this *MyLinkedList) DeleteAtIndex(index int) {//h* 0 1 2 3 4	;0if this.Size > index {DummyHead := this.DummyHeadcur := DummyHeadfor ; index > 0; index-- {cur = cur.Next}cur.Next = cur.Next.Nextthis.DummyHead = DummyHeadthis.Size--}}

这篇关于Golang leetcode707 设计链表 (链表大成)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/561584

相关文章

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.

golang中slice扩容的具体实现

《golang中slice扩容的具体实现》Go语言中的切片扩容机制是Go运行时的一个关键部分,它确保切片在动态增加元素时能够高效地管理内存,本文主要介绍了golang中slice扩容的具体实现,感兴趣... 目录1. 切片扩容的触发append 函数的实现2. runtime.growslice 函数gro

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Golang interface{}的具体使用

《Golanginterface{}的具体使用》interface{}是Go中可以表示任意类型的空接口,本文主要介绍了Golanginterface{}的具体使用,具有一定的参考价值,感兴趣的可以了... 目录一、什么是 interface{}?定义形China编程式:二、interface{} 有什么特别的?✅