203. Remove Linked List Elements
To remove an element in a linked list, just link the third element to the first element and return the first element. Therefore, do conduct a delete, we need at least 3 elements: cur, cur.next, cur.next.next. To remove the first element, one needs to assign head = head.next. To simplify the code, we can create a dummy head before the head and return dummyhead.next
class ListNode():
def __init__(self,val=0,next=None):
self.val = val
self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummyhead = ListNode(next=head)
cur = dummyhead
while(cur.next != None):
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return dummyhead.next
707. Design Linked List
cur = head.next
pre = head
because a dummy head is defined at first. Therefore the first element should be head.next
to add a node at index i, node.next = i.next, i-1.next = node. Move from right to left so we don't lose the link.
to delete a node at index i, i-1.next = i+1.next
class Node:
def __init__(self, next=None, val=0):
self.next = next
self.val = val
class MyLinkedList:
def __init__(self):
self.head = Node()
self.size = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.size:
return -1
cur = self.head.next
while index > 0:
cur = cur.next
index -= 1
return cur.val
def addAtHead(self, val: int) -> None:
new_node = Node(val=val)
new_node.next = self.head.next
self.head.next = new_node
self.size += 1
def addAtTail(self, val: int) -> None:
new_node = Node(val=val)
cur = self.head
while(cur.next):
cur = cur.next
cur.next = new_node
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index > self.size or index < 0:
return
if index == self.size:
self.addAtTail(val)
return
new_node = Node(val=val)
pre = self.head
while(index>0):
pre = pre.next
index -= 1
new_node.next = pre.next
pre.next = new_node
self.size += 1
def deleteAtIndex(self, index: int) -> None:
if index >= self.size or index < 0:
return
pre = self.head
while(index):
pre = pre.next
index -= 1
pre.next = pre.next.next
self.size -=1
inplement the bi-directional link list:
problem:
1. dont use get_node(index-1) to get pre node. use node.pre instead. otherwise at index 0 index-1 = -1 doesn't make sense
2. when searching from the back, use size - index -1
3. add self to all the self function and fields
class Node:
def __init__(self, value=0):
self.next = None
self.pre = None
self.val = value
class MyLinkedList:
def __init__(self):
self.head = Node()
self.tail = Node()
self.head.next = self.tail
self.tail.pre = self.head
self.size = 0
def get_node_by_idx(self, index):
if index < 0 or index >= self.size:
return
else:
if index <= self.size//2:
cur = self.head.next
while index:
cur = cur.next
index -= 1
return cur
else:
index = self.size-1-index
cur = self.tail.pre
while index:
cur = cur.pre
index -= 1
return cur
def update(self, node1, node2, val):
new_node = Node(value=val)
node1.next = new_node
node2.pre = new_node
new_node.pre = node1
new_node.next = node2
self.size += 1
def get(self, index: int) -> int:
val = self.get_node_by_idx(index)
if val == None:
return -1
else:
return val.val
def addAtHead(self, val: int) -> None:
self.update(self.head, self.head.next, val)
def addAtTail(self, val: int) -> None:
self.update(self.tail.pre, self.tail, val)
def addAtIndex(self, index: int, val: int) -> None:
if index == 0:
self.addAtHead(val)
elif index == self.size:
self.addAtTail(val)
else:
node_before_index = self.get_node_by_idx(index-1)
if node_before_index == None:
return
self.update(node_before_index, node_before_index.next, val)
def deleteAtIndex(self, index: int) -> None:
if self.get_node_by_idx(index) == None:
return
node_before_index = self.get_node_by_idx(index).pre
node_after_index = node_before_index.next.next
node_before_index.next = node_after_index
node_after_index.pre = node_before_index
self.size -= 1
206. Reverse Linked List
Two Pointers:
need a pre pointer for i-1; cur pointer for i, and temp for i+1
in each loop, first get temp, while it still lasts. then assign cur.next = pre. then move pre and cur rightward. move pre = cur first then move cur = temp.
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None:
return head
pre = None
cur = head
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre
Recursion:
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
def reverse(pre,cur):
if not cur:
return pre
temp = cur.next
cur.next = pre
return reverse(cur,temp)
return reverse(None,head)