一、链表基础定义和操作
链表操作的两种方式:
直接使用原来的链表来进行操作。
设置一个虚拟头结点在进行操作。(更简单)
定义链表:
class Node:
def __init__(self, val):
self.val = val
self.next = None
获取index节点值:
def get(self, index: int) -> int:
"""
Get the value of the index-th node in the linked list. If the index is invalid, return -1.
"""
if 0 <= index < self._count:
node = self._head
for _ in range(index + 1):
node = node.next
return node.val
else:
return -1
插入节点:
2,3,4可以看成是一个操作。由于一开始使用了虚拟节点操作,那么在最前面和中间后面操作本质上是一样的
def addAtHead(self, val: int) -> None:
"""
Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
"""
self.addAtIndex(0, val)
def addAtTail(self, val: int) -> None:
"""
Append a node of value val to the last element of the linked list.
"""
self.addAtIndex(self.size, val)
def addAtIndex(self, index: int, val: int) -> None:
"""
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
"""
# If index is greater than the length,
# the node will not be inserted.
if index > self.size:
return
# [so weird] If index is negative,
# the node will be inserted at the head of the list.
if index < 0:
index = 0
self.size += 1
# find predecessor of the node to be added
pred = self.head
for _ in range(index):
pred = pred.next
# node to be added
to_add = ListNode(val)
# insertion itself
to_add.next = pred.next
pred.next = to_add
删除节点:
def deleteAtIndex(self, index: int) -> None:
"""
Delete the index-th node in the linked list, if the index is valid.
"""
# if the index is invalid, do nothing
if index < 0 or index >= self.size:
return
self.size -= 1
# find predecessor of the node to be deleted
pred = self.head
for _ in range(index):
pred = pred.next
# delete pred.next
pred.next = pred.next.next
二、一些经典题目
1、环形列表
2、反转链表
3、删除第N个节点
等等
常常涉及到的操作有:快慢指针(快慢指针经常考察两个指针相遇的问题)、哈希表