203.移除链表元素
题目链接
leetcode.cn/problems/re…
文章链接
programmercarl.com/0203.%E7%A7…
视频链接
www.bilibili.com/video/BV18B…
看到题目的第一想法
这道题我的第一想法有一个疑问,如果删除的是头结点怎么办,这个我不知道怎么解。
看完代码随想录之后的想法
看完卡哥的视频我发现可以在链表前面加一个虚拟头结点,这样就完美地解决了“如果删除的是头结点”这样一个问题,到时候直接返回虚拟头结点的下一个节点就可以了,完美地解决了我的问题。下面附上我的go语言代码。
func removeElements(head *ListNode, val int) *ListNode {
dummyHead := new(ListNode)
cursor := dummyHead
cursor.Next = head
for cursor.Next != nil {
if cursor.Next.Val == val {
cursor.Next = cursor.Next.Next
} else {
cursor = cursor.Next
}
}
return dummyHead.Next
}
实现过程中遇到的困难
这道题不算难,但是写的时候也有一些细节问题,比如我搞忘了go语言怎么定义链表了,还专门去百度了一下。另外,定义的虚拟头结点dummyHead不能直接拿来进行后面的操作,必须写一句cursor := dummyHead来进行一个转换,不然就将整个链表全改了,我最开始直接用dummyHead来进行操作,最后结果始终为空。一定要记住最后返回的是dummyHead.Next,因为头结点可能被删了,所以返回head不完全对。
今日收获
今天学到了虚拟头结点的方式来解决链表问题,对于处理头结点的问题很关键。
707.设计链表
题目链接
leetcode.cn/problems/de…
文章链接
programmercarl.com/0707.%E8%AE…
视频链接
www.bilibili.com/video/BV1FU…
看到题目的第一想法
这道题看到的时候比较头疼,再加上我也在实习,时间比较紧,所以等到周末再来做这道题。
看完代码随想录之后的想法
卡哥在视频里也运用了虚拟头结点的方式来解题,还讲到了一系列细节问题,这道题周末做了再来好好总结。下面附上官方代码,官网的代码还有单向链表和双向链表的版本。 单向链表:
type MyLinkedList struct {
head *ListNode
size int
}
func Constructor() MyLinkedList {
return MyLinkedList{&ListNode{}, 0}
}
func (l *MyLinkedList) Get(index int) int {
if index < 0 || index >= l.size {
return -1
}
cur := l.head
for i := 0; i <= index; i++ {
cur = cur.Next
}
return cur.Val
}
func (l *MyLinkedList) AddAtHead(val int) {
l.AddAtIndex(0, val)
}
func (l *MyLinkedList) AddAtTail(val int) {
l.AddAtIndex(l.size, val)
}
func (l *MyLinkedList) AddAtIndex(index, val int) {
if index > l.size {
return
}
index = max(index, 0)
l.size++
pred := l.head
for i := 0; i < index; i++ {
pred = pred.Next
}
toAdd := &ListNode{val, pred.Next}
pred.Next = toAdd
}
func (l *MyLinkedList) DeleteAtIndex(index int) {
if index < 0 || index >= l.size {
return
}
l.size--
pred := l.head
for i := 0; i < index; i++ {
pred = pred.Next
}
pred.Next = pred.Next.Next
}
func max(a, b int) int {
if b > a {
return b
}
return a
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/design-linked-list/solution/she-ji-lian-biao-by-leetcode-solution-abix/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
双向链表:
type node struct {
val int
next, prev *node
}
type MyLinkedList struct {
head, tail *node
size int
}
func Constructor() MyLinkedList {
head := &node{}
tail := &node{}
head.next = tail
tail.prev = head
return MyLinkedList{head, tail, 0}
}
func (l *MyLinkedList) Get(index int) int {
if index < 0 || index >= l.size {
return -1
}
var curr *node
if index+1 < l.size-index {
curr = l.head
for i := 0; i <= index; i++ {
curr = curr.next
}
} else {
curr = l.tail
for i := 0; i < l.size-index; i++ {
curr = curr.prev
}
}
return curr.val
}
func (l *MyLinkedList) AddAtHead(val int) {
l.AddAtIndex(0, val)
}
func (l *MyLinkedList) AddAtTail(val int) {
l.AddAtIndex(l.size, val)
}
func (l *MyLinkedList) AddAtIndex(index, val int) {
if index > l.size {
return
}
index = max(0, index)
var pred, succ *node
if index < l.size-index {
pred = l.head
for i := 0; i < index; i++ {
pred = pred.next
}
succ = pred.next
} else {
succ = l.tail
for i := 0; i < l.size-index; i++ {
succ = succ.prev
}
pred = succ.prev
}
l.size++
toAdd := &node{val, succ, pred}
pred.next = toAdd
succ.prev = toAdd
}
func (l *MyLinkedList) DeleteAtIndex(index int) {
if index < 0 || index >= l.size {
return
}
var pred, succ *node
if index < l.size-index {
pred = l.head
for i := 0; i < index; i++ {
pred = pred.next
}
succ = pred.next.next
} else {
succ = l.tail
for i := 0; i < l.size-index-1; i++ {
succ = succ.prev
}
pred = succ.prev.prev
}
l.size--
pred.next = succ
succ.prev = pred
}
func max(a, b int) int {
if b > a {
return b
}
return a
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/design-linked-list/solution/she-ji-lian-biao-by-leetcode-solution-abix/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
实现过程中遇到的困难
做了再写吧!
今日收获
有点懵!
206.反转链表
题目链接
leetcode.cn/problems/re…
文章链接
programmercarl.com/0206.%E7%BF…
视频链接
www.bilibili.com/video/BV1nB…
看到题目的第一想法
这道题的第一想法就是有一个问题我不知道怎么解决。举个例子,假设链表1->2->3,反转链表则是1<-2<-3,当只改变了一个箭头的方向时,那么会变成1<-2->3,这是不允许的,2这个元素有两个next,这是不允许的,我就卡在了这个问题上。
看完代码随想录之后的想法
看完卡哥的视频后,我发现我多虑了,用双指针来解这道题,根本不存在这个问题,因为我第一想法的那个疑惑之处只是链表操作的其中一步,箭头会陆续反过来的,最重要的是返回的要是全部反转完的链表。这道题用双指针法恰到好处。两个指针,一个pre,一个cur,pre先定义为空结点,cur指向head,先把cur.Next给保存下来,接下来的一步很重要,cur.Next = pre,这样的话下一步才能将cur移动到cur.Next,于是pre = cur,最后再把保存的元素赋给cur。下面是我写的go语言代码:
func reverseList(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil {
temp := cur.Next
cur.Next = pre
pre = cur
cur = temp
}
return pre
}
实现过程中遇到的困难
困难在上一个章节已经讲到了。
今日收获
再一次巩固了双指针法。