203.移除链表元素
链接
思路
这里来给链表添加一个虚拟头结点为新的头结点,此时要移除这个旧头结点元素1。
这样是不是就可以使用和移除链表其他节点的方式统一了呢?
来看一下,如何移除元素1 呢,还是熟悉的方式,然后从内存中删除元素1。
最后呢在题目中,return 头结点的时候,别忘了 return dummyNode->next;, 这才是新的头结点。
代码
func removeElements(head *ListNode, val int) *ListNode {
dummy:=&ListNode{}
dummy.Next=head
cur:=dummy
for cur!=nil&&cur.Next!=nil{
if cur.Next.Val==val{
cur.Next=cur.Next.Next
}else{
cur=cur.Next
}
}
return dummy.Next
}
困难
记得设置虚拟头结点
707.设计链表
链接
思路
代码
type MyLinkedList struct {
Dummy *Node
Size int
}
type Node struct {
Next *Node
Val int
}
func Constructor() MyLinkedList {
return MyLinkedList{&Node{},0}
}
func (this *MyLinkedList) Get(index int) int {
if !(index>=0&&index<this.Size){
return -1
}
cur:=this.Dummy.Next
for i:=0;i<index;i++{
cur=cur.Next
}
return cur.Val
}
func (this *MyLinkedList) AddAtHead(val int) {
this.Dummy.Next=&Node{this.Dummy.Next,val}
this.Size++
}
func (this *MyLinkedList) AddAtTail(val int) {
cur:=this.Dummy
for cur.Next!=nil{
cur=cur.Next
}
cur.Next=&Node{Val:val}
this.Size++
}
func (this *MyLinkedList) AddAtIndex(index int, val int) {
if index==this.Size{
this.AddAtTail(val)
return
}
if index>this.Size||index<0{
return
}
cur:=this.Dummy
for i:=0;i<index;i++{
cur=cur.Next
}
cur.Next=&Node{cur.Next,val}
this.Size++
}
func (this *MyLinkedList) DeleteAtIndex(index int) {
if index>=0&&index<this.Size{
cur:=this.Dummy
for i:=0;i<index;i++{
cur=cur.Next
}
cur.Next=cur.Next.Next
this.Size--
}
}
困难
记得设置虚拟头结点
206.反转链表
链接
思路
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。 此时我们return pre指针就可以了,pre指针就指向了新的头结点。
代码
func reverseList(head *ListNode) *ListNode {
pre:=(*ListNode)(nil)
cur:=head
for cur!=nil{
next:=cur.Next
cur.Next=pre
pre=cur
cur=next
}
return pre
}
今日收获
要有设计虚拟头节点的思想,这样操作头结点的时候就可以直接操作了,不用对头结点重新赋值。
链表反转双指针法和递归法。