#707. 设计链表
题目
设计链表,使得链表有以下功能:
- 得到indexth 元素的值
- 从头加元素
- 从尾加元素
- 在indexth Node前边加元素
- 把indexth 的Node删除
解答
单链表
增、减元素:找到prev和after,再进行next的指针操作。
#Node class
class ListNode:
def __init__(self,val):
self.val = val
self.next = None
#has attribute of: how many nodes inside, and the pseudo-head node
class MyLinkedList:
def __init__(self):
self.size = 0 #添加的节点数
self.head = ListNode(0) #虚拟头部节点
def get(self, index: int) -> int:
#invalid cases of index
if index < 0 or index >= self.size:
return -1
#index + 1, 因为head是幽灵head
curr = self.head
for i in range(index + 1):
curr = curr.next
return curr.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:
#如果index > size 则不考虑
if index > self.size:
return
#如果index < 0, 那么仍然valid,cast index为0
if index < 0:
index = 0
#add size don't forget
self.size += 1
#find predecessor
pred = self.head
for i in range(index):
pred = pred.next
after = pred.next
to_add = ListNode(val)
pred.next = to_add
to_add.next = after
def deleteAtIndex(self, index: int) -> None:
#如果index小于self.size, 证明valid,则再进行运算
if index < self.size:
self.size -= 1
pred = self.head
for i in range(index):
pred = pred.next
after = pred.next.next
pred.next = after
###双链表
#Node class
class ListNode:
def __init__(self,val):
self.val = val
self.next = None
self.prev = None
#has attribute of: how many nodes inside, and the pseudo-head node
class MyLinkedList:
def __init__(self):
self.size = 0 #添加的节点数
self.head = ListNode(0) #虚拟头部节点
self.tail = ListNode(0) #虚拟尾部节点
self.head.next = self.tail
self.tail.prev = self.head
def get(self, index: int) -> int:
#invalid cases of index
if index < 0 or index >= self.size:
return -1
#如果index > 一半,则往后找
if index >= self.size // 2:
curr = self.tail
for i in range(self.size - index):
curr = curr.prev
#如果index < 一半,则往前找
else:
curr = self.head
for i in range(index + 1):
curr = curr.next
return curr.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 > self.size:
return
if index < 0:
index = 0
#如果index 小于一半,则从前往后找,输出prev,succ
if index < self.size // 2:
pred = self.head
for i in range(index):
pred = pred.next
succ = pred.next
#如果index 大于一半,则从后往前找,输出prev,succ
else:
succ = self.tail
for i in range(self.size - index):
succ = succ.prev
pred = succ.prev
#处理链表的指针关系
#add size don't forget
self.size += 1
to_add = ListNode(val)
pred.next = to_add
to_add.next = succ
succ.prev = to_add
to_add.prev = pred
def deleteAtIndex(self, index: int) -> None:
if index >= self.size or index < 0:
return
#如果index 小于一半,则从前往后找,输出prev,succ
if index < self.size // 2:
pred = self.head
for i in range(index):
pred = pred.next
succ = pred.next.next
#如果index 大于一半,则从后往前找,输出prev,succ
else:
succ = self.tail
for i in range(self.size - 1 - index):
succ = succ.prev
pred = succ.prev.prev
self.size -= 1
pred.next = succ
succ.prev = pred
收获
- MyLinkedList有两个fields: size (Node的数量),以及 head (幽灵节点,指向第一个元素,类同dummy)
- 双链表记得创建head和tail
- 画图大法