题目描述:
在链表类中实现这些功能:
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class MyLinkedList(object):
def __init__(self):
self.size = 0
self.head = ListNode(0)
def get(self, index):
if index < 0 or index >= self.size:
return -1
cur = self.head
for _ in range(index + 1):
cur = cur.next
return cur.val
def addAtIndex(self, index, val):
if index > self.size:
return
if index < 0:
index = 0
self.size += 1
pred = self.head
for _ in range(index):
pred = pred.next
toAddNode = ListNode(val)
toAddNode.next = pred.next
pred.next = toAddNode
def addAtHead(self, val):
self.addAtIndex(0, val)
def addAtTail(self, val):
self.addAtIndex(self.size, val)
def deleteAtIndex(self, index):
if index >= self.size or index < 0:
return
self.size -= 1
predDel = self.head
for _ in range(index):
predDel = predDel.next
predDel.next = predDel.next.next
# 双链表
# 相对于单链表, Node新增了prev属性
class Node:
def __init__(self, val):
self.val = val
self.prev = None
self.next = None
class MyLinkedList:
def __init__(self):
self._head, self._tail = Node(0), Node(0) # 虚拟节点
self._head.next, self._tail.prev = self._tail, self._head
self._count = 0 # 添加的节点数
def _get_node(self, index: int) -> Node:
# 当index小于_count//2时, 使用_head查找更快, 反之_tail更快
if index >= self._count // 2:
# 使用prev往前找
node = self._tail
for _ in range(self._count - index):
node = node.prev
else:
# 使用next往后找
node = self._head
for _ in range(index + 1):
node = node.next
return node
def get(self, index: int) -> int:
if 0 <= index < self._count:
node = self._get_node(index)
return node.val
else:
return -1
def addAtHead(self, val: int) -> None:
self._update(self._head, self._head.next, val)
def addAtTail(self, val: int) -> None:
self._update(self._tail.prev, self._tail, val)
def addAtIndex(self, index: int, val: int) -> None:
if index < 0:
index = 0
elif index > self._count:
return
node = self._get_node(index)
self._update(node.prev, node, val)
def _update(self, prev: Node, next: Node, val: int) -> None:
# 计数累加
self._count += 1
node = Node(val)
prev.next, next.prev = node, node
node.prev, node.next = prev, next
def deleteAtIndex(self, index: int) -> None:
if 0 <= index < self._count:
node = self._get_node(index)
# 计数-1
self._count -= 1
node.prev.next, node.next.prev = node.next, node.prev