代码随想录算法训练营第三天(链表篇)|Leetcode203移除链表元素,Leetcode707设计链表,Leetcode206反转链表
Leetcode 203 移除链表元素
题目链接: 移除链表元素
题目要求删除链表中所有特定值的节点。
如 1->2->2->1->3,删去链表中所有的2,预期结果为1->1->3
思路:
当涉及到链表节点操作时,我们首先应该想到使用虚拟头节点 dummyHead。因为无论是插入链表节点还是删去链表节点,都需要经过修改节点相对次序这一过程。假设需要修改的节点涉及头节点,则需要为头节点添加额外的处理逻辑。使用虚拟头节点能够将处理链表头节点的过程转换为修改链表中间节点的过程,有效保证程序对节点处理逻辑的一致性。
具体代码实现
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy_head = ListNode(0, next=head)
cur = dummy_head
while cur.next: # 此处使用while而不是if,可能有连续多个满足目标值的节点,需要一并删除
if cur.next.val == val:
next_node = cur.next.next
cur.next = next_node
else:
cur = cur.next
return dummy_head.next
时间复杂度: O(n)
Leetcode 707 设计链表
题目链接: 设计链表
本题要求实现链表基本的增删查功能
思路: 本题主要考察对链表数据结构的理解与代码实现能力。注意到题目中仅给出链表类,因此,我们还需要自行创建链节点类。
为了方便操纵节点,我们为链表类添加一个虚拟链表头节点。同时,由于功能函数中涉及将元素插入到特定索引的操作,为了验证索引的有效性,我们需要在链表类中动态维护链表大小,以避免越界访问。
具体代码实现
class MyLinkedNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.dummyHead = MyLinkedNode()
self.size = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.size:
return -1
cur = self.dummyHead.next
while index:
cur = cur.next
index -= 1
return cur.val
# 头插和尾插函数都可以被视作一种插入的特殊情况,封装在特定下标处插入节点的函数即可。
def addAtHead(self, val: int) -> None:
self.addAtIndex(0, val)
def addAtTail(self, val: int) -> None:
self.addAtIndex(self.size, val)
def addAtIndex(self, index: int, val: int) -> None:
if index < 0 or index > self.size:
return
newNode = MyLinkedNode(val)
cur = self.dummyHead
while index:
cur = cur.next
index -= 1
nextNode = cur.next
cur.next = newNode
newNode.next = nextNode
self.size += 1
def deleteAtIndex(self, index: int) -> None:
if index < 0 or index >= self.size:
return
cur = self.dummyHead
while index:
cur = cur.next
index -= 1
nextNode = cur.next.next
cur.next = nextNode
self.size -= 1
Leetcode 206 反转链表
题目链接: 反转链表
给定一个链表,返回将该链表反转后,该链表的头节点。
1->2->3 反转后得到 3->2->1, 返回3
思路:
本题既可以通过迭代法,从前向后遍历链表,并在遍历的过程中反转链表;也可以通过递归法,递归反转整个链表。
具体代码实现
# 迭代法:
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev, cur = None, head
while cur:
next = cur.next
cur.next = prev
prev = cur
cur = next
return prev
# 递归法
# 递归法的核心思想为: 递归到链表的末尾,找到反转后的新头结点(即原来的尾结点), 并在回溯过程中,把每个节点的 next 指针反向。
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 明确递归终止条件为: 当前处理的链表片段中没有节点或仅有一个节点,此时为完成反转的状态,直接返回头节点
if not head or not head.next:
return head
newHead = self.reverseList(head.next) # 已经完成反转部分链表的头节点
head.next.next = head # 将已经完成反转链表的头节点进行反转,使其指向原链表的头节点
head.next = None # 避免出现环
return newHead
复杂度分析: 时间复杂度: O(n),空间复杂度: O(1)(迭代法); 时间复杂度: O(n), 空间复杂度: O(n)(迭代法)

浙公网安备 33010602011771号