LC 203, 707, 206
First part of Linked List.
LC 209. Minimum Size Subarray Sum
Logic
In order, we have:
p
a
r
e
n
t
→
c
u
r
→
c
u
r
.
n
e
x
t
parent \rightarrow cur \rightarrow cur.next
parent→cur→cur.next
- Set a
parent
node, if thecur
node shouldn’t be deleted, then we can set it as parent. - Upon deletion, we can just assign
parent.next = cur.next
, socur
in between is deleted.
# LC 203
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
if not head:
return head
cur = head
parent = None
while cur:
if cur.val != val:
parent = cur
else:
if not parent:
head = cur.next
else:
parent.next = cur.next
cur = cur.next
return head
707. Design Linked List
Not really possible for me to finish in 1 hr, more practice is needed.
Logic
I used a double linked-list with a head node.
- So I actually has a
head
node,- where
head.next
points to the really first elem. - and
head.prev
points to the back elem.
- where
class MyLinkedList:
def __init__(self, val=None, next=None, prev=None):
self.val = val
self.next = next
self.prev = prev
def get(self, index: int) -> int:
if index < 0:
return -1
count = 0
# start with the head
cur: MyLinkedList = self.next
while count < index and cur and cur.next:
cur = cur.next
count += 1
if not cur or cur.val is None or count < index:
return -1
return cur.val
def addAtHead(self, val: int) -> None:
new_node = MyLinkedList(val=val, next=self.next)
if self.next is not None:
self.next.prev = new_node
self.next = new_node
if self.prev is None:
self.prev = new_node
def addAtTail(self, val: int) -> None:
tail = self.prev
new_node = MyLinkedList(val=val, next=None, prev=tail)
if tail:
tail.next = new_node
else:
self.next = new_node
self.prev = new_node
def addAtIndex(self, index: int, val: int) -> None:
if index < 0:
return
count = 0
cur: MyLinkedList = self
while count < index and cur and cur.next:
cur = cur.next
count += 1
if count < index:
return
new_node = MyLinkedList(val=val, next=cur.next, prev=cur)
if cur.next:
cur.next.prev = new_node
cur.next = new_node
if cur == self.prev:
self.prev = new_node
def deleteAtIndex(self, index: int) -> None:
if index < 0:
return
count = 0
cur: MyLinkedList = self
while count < index and cur and cur.next:
cur = cur.next
count += 1
if count < index or not cur:
return
if cur.next and cur.next.next:
cur.next = cur.next.next
cur.next.prev = cur
elif cur.next:
cur.next = None
self.prev = cur
# for the sake of debugging
def __repr__(self) -> str:
ret = "head"
cur = self.next
while cur and cur.val is not None:
ret += f"->{str(cur.val)}"
cur = cur.next
return ret
206. Reverse Linked List
Logic:
- Create a new Linked List from the end.
- Or we can reverse the link using another ptr.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
cur = head
ret = None
if cur is not None:
ret = ListNode(cur.val)
while cur.next is not None:
cur = cur.next
new_node = ListNode(cur.val, ret)
ret = new_node
return ret
Summary:
-
Overall, the linked list part is not yet hard for me now, but the design for the linked list is crucial, and the condition for
None
check is necessary. -
Total time: 4-5 hrs ish.