Basics¶
Design¶
from typing import Optional
class DoublyLinkedListNode:
def __init__(self, val, prev=None, next=None):
self.val = val
self.prev = prev
self.next = next
def __str__(self):
return f"{self.val}{f' <-> {self.next}' if self.next else ''}"
class DoublyLinkedList:
def __init__(self):
self.sentinel_head = DoublyLinkedListNode(val=None)
self.sentinel_tail = DoublyLinkedListNode(val=None, prev=self.sentinel_head)
self.sentinel_head.next = self.sentinel_tail
self.len = 0
@property
def head(self):
if self.sentinel_head.next != self.sentinel_tail:
return self.sentinel_head.next
@property
def tail(self):
if self.sentinel_tail.prev != self.sentinel_head:
return self.sentinel_tail.prev
def goTo(self, index: int) -> Optional[DoublyLinkedListNode]:
if index == -1:
return self.sentinel_head
elif index == self.len:
return self.sentinel_tail
elif index == self.len - 1:
return self.sentinel_tail.prev
elif index == self.len - 2:
return self.sentinel_tail.prev.prev
elif 0 <= index < self.len:
p = self.head
for _ in range(index):
p = p.next
return p
def insert(self, index: int, val):
if 0 <= index <= self.len:
prev = self.goTo(index - 1)
prev.next = DoublyLinkedListNode(val=val, prev=prev, next=prev.next)
prev.next.next.prev = prev.next
self.len += 1
def insertAtHead(self, val):
return self.insert(index=0, val=val)
def insertAtTail(self, val):
return self.insert(index=self.len, val=val)
def get(self, index: int):
if 0 <= index < self.len:
return self.goTo(index).val
return -1
def remove(self, index: int):
if 0 <= index < self.len:
prev = self.goTo(index - 1)
prev.next.next.prev = prev
prev.next = prev.next.next
self.len -= 1
def __len__(self):
return self.len
def __str__(self):
return str(self.sentinel_head.next)