class ListNode:
def __init__(self, val=0, next=None) -> None:
self.val = val
self.next = next
def __repr__(self) -> str:
return str(self.val)
class LinkedList:
def __init__(self, head=None) -> None:
self.head = head
@classmethod
def build_from_list(cls, lst):
if lst:
dummy = ListNode()
curr = dummy
for v in lst:
curr.next = ListNode(v)
curr = curr.next
return cls(dummy.next)
def get_nth_node(self, index):
curr = self.head
for _ in range(index):
curr = curr.next
return curr
def __iter__(self):
curr = self.head
while curr:
yield curr.val
curr = curr.next
def __repr__(self) -> str:
return "->".join([str(e) for e in self])
def __len__(self):
return sum(1 for _ in self)
def __getitem__(self, index):
if index < 0:
index = len(self) + index
for k, v in enumerate(self):
if k == index:
return v
def __setitem__(self, index, val):
if index < 0:
index = len(self) + index
curr = self.get_nth_node(index)
curr.val = val
def __delitem__(self, index):
if index < 0:
index = len(self) + index
if index == 0:
prev = ListNode(0, self.head)
else:
prev = self.get_nth_node(index-1)
curr = prev.next
prev.next = curr.next
return curr
def insert(self, val, index=0):
if not (0 <= index <= len(self)):
raise IndexError("list index out of range")
node = ListNode(val)
if not index:
node.next = self.head
self.head = node
else:
prev = self.get_nth_node(index-1)
node.next = prev.next
prev.next = node
def search(self, val):
for k, v in enumerate(self):
if v == val:
return k
else:
return -1
def delete(self, val):
index = self.search(val)
del self[index]
def reverse(self):
prev, curr = None, self.head
while curr:
temp = curr.next
curr.next = prev
prev = curr
curr = temp
self.head = prev
return prev
def get_nth_node_from_end(self, n):
fast, slow = self.head, self.head
for i in range(n):
if not fast:
return
fast = fast.next
while fast:
slow = slow.next
fast = fast.next
return slow