今天是day3,今天的内容如下:
第一题为移除链表元素,简而言之为,给定一个链表,要求删除所有值为val的节点并最终把头结点输出。
逻辑如下:
假设链表开头有一系列值为 val 的节点,我们使用两个判断来确保可以跳过它们。
现在 cur 指向链表的第一个非 val 节点。
如果 cur.Next 为 nil,那么我们已经遍历完整个链表,不需要再进行判断。
否则,我们检查 cur.Next 的值是否等于 val。如果是,我们将 cur.Next 跳过,直接指向下一个节点的下一个节点,从而删除了值为 val 的节点。
如果 cur.Next 的值不等于 val,我们将 cur 移动到下一个节点,以便继续遍历链表。虚拟头结点的话也仅在此逻辑上做些修改
func removeelements(head *ListNode,val int) *ListNode {
for head!=nil && head.Val==val{
head = head.next
}
cur:=head
for cur!=nil && cur.Next!=nil{
if cur.Next.Val == val{
cur.Next = cur.Next.Next
}else{
cur = cur.Next
}
}
return head
}
法二虚拟头结点法:
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
}
python虚拟头结点法:
class solution:
def removeElements(self,head:Option[ListNode],val:int) ->Option[ListNode]:
dummy_head = ListNode(next = head)
current = dummy_head
while current.next:
if current.next.val == val:
current.next = current.next.next
else:
current = current.next
return dummy_head.next
第二题为构造链表以及定义相关方法:
用go语言实现:
type MyLinkedList struct{
dummy *Node
}
type Node struct{
Val int
Next *Node
Pre *Node
}
func Constructor() MyLinkedList {
rear := &Node{
Val:-1,
Next:nil,
Pre:nil,
}
rear.Next = rear
rear.Pre = rear
return MyLinkedList{rear}
}
func (this *MyLinkedList) Get(index int){
head = this.dummy.Next
for head!= this.dummy && index > 0{
index--
head = head.Next
}
if 0!= index {
return -1
}
return head.Val
}
func (this *MyLinkedList) AddAtHead(val int) {
dummy:=this.dummy
node:=&Node{
Val:val,
Next:dummy.Next,
Pre:dummy,
}
dummy.Next.Pre = node
dummy.Next = node
}
func (this *MyLinkedList) AddAtTail(val int) {
dummy:=this.dummy
rear:=&Node{
Val:val,
Next:dummy,
Pre:dummy.Pre,
}
dummy.Pre.Next = rear
dummy.Pre = rear
}
func (this *MyLinkedList) AddAtIndex(index int,val int) {
head:=this.dummy.Next
for head != this.dummy && index > 0 {
head = head.Next
index--
}
if index > 0{
return
}
node:=&Node{
Val:val,
Next:head,
Pre:head.Pre,
}
head.Pre.Next = node
head.Pre = ndoe
}
func (this *MyLinkedList) DeleteAtIndex(index int){
if this.dummy.Next == this.dummy {
return
}
head := this.dummy.Next
for head.Next != this.dummy&&index >0 {
head = head.Next
index--
}
if index == 0{
head.Next.Pre = head.Pre
head.Pre.Next = head.Next
}
}
python版本:
class ListNode:
def __init__(self,val-0,prev=None,next=None):
self.val =val
self.prev = prev
self.next = next
class MyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def get(self,index:int) -> int:
if index < 0 or index >= index.size:
return -1
if index < self.size // 2:
current = self.head
for i in range(index):
current = current.next
else:
current = self.tail
for i in range(self.size - index -1):
current = current.prev
return current.val
def addAthead(self,val:int) -> None:
new_node = ListNode(val,None,self.head)
if self.head:
self.head.prev = new_node
else:
self.tail = new_node
self.head = new_ndoe
self.size+=1
def addAtTail(self,val:int) -> None:
new_ndoe=ListNode(val,self.tail,None)
if self.tail:
self.tail.next = new_node
else:
self.head = new_node
self.tail = new_node
self.size+=1
def addAtindex(self,index:int,val:int)->None:
if index < 0 or index > self.size:
return
if index == 0:
self.addAthead(val)
elif index == self.size:
self.addAttail(val)
else:
if index < self.size // 2:
current = self.head
for i in range(index -1):
current = current.next
else:
current = self.tail
for i in range(self.size - index):
current = current.prev
new_node = ListNode(val,current,current.next)
current.next.prev = new_node
current.next = new_node
self.size+=1
def deleteAtindex(self,index:int) ->None:
if index < 0 or index >= self.size:
return
if index == 0:
self.head = self.head.next
if self.head:
self.head.prev = Noe
else:
self.tail = None
elif index == self.size - 1:
self.tail = self.tail.prev
if self.tail:
self.tail.next = None
else:
self.head = None
else:
if index < self.size // 2:
current = self.head
for i in range(index):
current = current.next
else:
current = self.tail
for i in range(self.size - index -1):
current = current.prev
current.prev.next = current.next
current.next.prev = current.prev
self.size-=1
题目三:反转链表,即在一个给定链表中,将其顺序反转:
定义两个指针 pre 和 cur。pre 初始化为 nil,cur 初始化为头节点 head。
遍历链表,直到 cur 为 nil,即链表的末尾。
在每次迭代中,首先保存 cur 的下一个节点到 next,以防止链表丢失。
然后将 cur.Next 指向 pre,这是反转链表的关键步骤,它将当前节点的指向改为前一个节点。
接着,移动 pre 和 cur。将 pre 更新为当前的 cur,将 cur 更新为 next(即原来的 cur.Next)。
当 cur 为 nil 时,pre 将指向原链表的最后一个节点,此时链表已经完全反转。
最后,返回新的头节点 pre。
这个过程实际上是在重新排列节点的指针,而不是物理地移动节点。每次迭代都将当前节点的 Next 指针指向前一个节点,从而实现链表的反转。
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
}
python版本:
class Solution:
def reverseList(self,head:Optional[ListNode]) ->Optional[ListNode]:
cur = head
pre = None
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre
python递归法:
即便是递归版本,其逻辑也仍然类似
class Solution:
def reverseList(self,head:Optional[ListNode]) ->Optipnal[ListNode]:
return self.reverse(head,None)
def reverse(self,cur:ListNode,pre:ListNode) -> ListNode:
if cur == None:
return pre
temp = cur.next
cur.next = pre
return self.reverse(temp,cur)
浙公网安备 33010602011771号