跟随carl代码随想录刷题
链表操作谨记一点:写清楚当前节点的下一个节点是哪个!eg:cur.next = …
删除节点:
cur.next = cur.next.next
添加节点:Newnode.next = cur.next
,cur.next = Newnode
203. 简单
删除链表中的元素
题目:给你一个链表的
头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val 的节点
,并返回 新的头节点
。
虚拟头节点
注意:return 头结点的时候,别忘了 return dummyNode->next;
, 这才是新的头结点
# 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: ListNode, val: int) -> ListNode:
dummy_head = ListNode(next=head) # 为链表添加一个虚拟头结点
cur = dummy_head # cur是当前位置,让当前位置位于虚拟节点处
while(cur.next != None): # 如果下一个节点不是链表结尾
if (cur.next.val == val): # 判断:如果下一个位置的val与题目给定的val相等
cur.next = cur.next.next # 让当前位置跳到下下一个位置处
else:
cur = cur.next # 否则,当前位置往前移动一个位置
return dummy_head.next # 返回虚拟头结点的下一个位置(也就是新的头结点的位置)
707. 中等
设计链表
题目:在链表类中实现这些功能:
获取第n个节点的数值
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。头部插入节点
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。尾部插入节点
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。第n个节点前插入节点
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。删除第n个节点
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
题目分析
统一使用虚拟头节点的方式
-
获取第n个节点的数值
注意:节点是从0开始的。第n个节点的索引是
n-1
。
如果n < 0
或n > size-1
,都是不合法的。
cur
是临时指针,用于操作链表,初始cur=dummyhead.next
,直接指向头节点。不能直接操作头节点!因为结束的时候要返回头节点,所以需要操作临时指针去完成任务# 代入`获取头节点`的情况,查看边界定义是否正确 while(n): # n=0时while不执行 cur = cur.next n -= 1 return cur.val
因为cur初始化时指向头节点,所以当
获取第0个节点,即头节点
的值时,不执行while循环
,直接返回cur.val
的值。 -
头部插入节点
# 因为要插入节点,所以要定义一个新节点 Newnode = new node() Newnode.next = dummyhead.next dummyhead = Newnode
-
尾部插入节点
Newnode = new node() # 定义一个新节点 cur = dummyhead # 初始化临时指针 while(cur.next != Null): cur = cur.next cur.next = Newnode
-
第n个节点前插入节点
要找到第n个节点之前的一个节点,然后进行操作。
一定要注意:cur位于n-1
,第n个节点是cur.next
Newnode = new node() # 定义一个新节点 cur = dummyhead # 初始化临时指针 # 找到`cur` while(n): cur = cur.next n -= 1 # 在`cur.next`进行插入节点 Newnode.next = cur.next cur.next = newnode
-
删除第n个节点
# 判断n的合法性 # 初始化 cur = dummyhead # 初始化临时指针 # 找到`cur` while(n): cur = cur.next n -= 1 # 删除`cur.next`节点 cur.next = cur.next.next size -= 1
代码
# 定义空链表
class Node:
def __init__(self, val):
self.val = val
self.next = None
class MyLinkedList:
def __init__(self):
self._head = Node(0) # 初始化虚拟头节点
self._count = 0 # 定义节点数(即链表长度)
def get(self, index: int) -> int:
if 0<= index < self._count: # 判断n的合法性
cur = self._head
while(index):
cur = cur.next
index -= 1
return cur.next.val
else:
return -1
def addAtHead(self, val: int) -> None:
# 直接引用现成函数,令n=0, 在n=0处插入节点
self.addAtIndex(0, val)
def addAtTail(self, val: int) -> None:
# 直接引用现成函数,在n = self._count处插入节点
self.addAtIndex(self._count, val)
def addAtIndex(self, index: int, val: int) -> None:
if index < 0:
index = 0
elif index > self._count:
return
if 0 <= index <= self._count: # 注意这里是`<=count`,涵盖尾部插入节点的情况
cur = self._head
Newnode = Node(val)
while(index):
cur = cur.next
index -= 1
Newnode.next = cur.next
cur.next = Newnode
self._count += 1 # 链表长度+1
def deleteAtIndex(self, index: int) -> None:
if 0 <= index < self._count:
cur = self._head
while(index):
cur = cur.next
index -= 1
cur.next = cur.next.next
self._count -= 1
# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)