题目1:移除链表元素
在题目图中,给出的是头节点,但是我们知道头节点的话就相当于知道了整个链表,所以示例中给出了整个列表。
解题思路:
遍历整个链表的节点,遇到相同的值便将节点指针指向下一个节点。
上边这个方法是根据前一个节点的指针来删除节点的,那么如果要删除的值是第一个节点的值呢?第一个节点并没有前一个节点那么这个怎么删除?
有两种解决方法:
- 删除的是头节点的话,另外写一种情况。
- 在头节点前定义一个虚拟节点,其指针指向头节点。
解法一:定义一个虚拟节点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy_node=ListNode(next=head)
current=dummy_node
while current.next:
if current.next.val==val:
current.next=current.next.next # 如果下一个节点是要删除的节点,那么将当前节点指针指向下下个节点。
else:
current=current.next
return dummy_node.next
注意:
最开始写的时候我有一个误区,最后return的不是dummy_node.next,而是current.next,然后就报错了。这是因为最开始的时候current=dummy_node,之后对current进行遍历删除,那么这个过程中也是对dummy_node遍历删除,dummy_node也会做出相应的改变,但是循环到最后一个节点的时候,current指向的是最后一个链表的节点了,如果返回current.next,就没办法找到整个链表了。(链表要根据头节点才能找到),所以还是返回链表的头节点dummy_node.next,这样才能找到整个链表。
时间复杂度:o(n),因为遍历了整个链表。
空间复杂度:o(1)。
题目二:设计链表。
实现根据下标索引返回链表元素节点,增加、删除链表节点。
题解:
class ListNode: # 创建一个链表
def __init__(self,val=0,next=None):
self.val=val
self.next=next
class MyLinkedList:
def __init__(self):
self.dummy_head=ListNode() # 这里创建的dummy_head只是一个节点,目前后边什么都没有。
self.size=0 # 该值表示的是链表的长度
def get(self, index: int) -> int: # 这里通过下标索引为什么要创建一个虚拟的节点
if index < 0 or index >= self.size:
return -1
current = self.dummy_head.next
for i in range(index):
current=current.next
return current.val
def addAtHead(self, val: int) -> None:
new_node=ListNode(val,self.dummy_head.next)
self.dummy_head.next=new_node
self.size+=1
return self.dummy_head.next
def addAtTail(self, val: int) -> None:
current=self.dummy_head
# while current.next:
# for i in range(self.size):
# current=current.next
# current.next=ListNode(val)
# self.size+=1
# return self.dummy_head.next
current = self.dummy_head
while current.next: #
current = current.next
current.next = ListNode(val)
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index<0 or index>self.size:
return
current=self.dummy_head
for i in range(index):
current=current.next
new_node=ListNode(val,current.next)
current.next=new_node
self.size+=1
return self.dummy_head.next
def deleteAtIndex(self, index: int) -> None:
if index<0 or index>=self.size:
return
current=self.dummy_head
for i in range(index):
current=current.next
current.next=current.next.next
self.size-=1
return self.dummy_head.next