Before attempting this problem, you should be comfortable with:
In a sorted circular linked list, we need to find the right spot to insert while maintaining sorted order. There are three cases to consider: the value fits between two existing nodes, the value is a new maximum or minimum (insert at the tail/head boundary), or all nodes have the same value.
We use two pointers to traverse the list, looking for the gap where our value belongs. The tail-to-head boundary is special because it's where the values wrap around from largest to smallest.
If we traverse the entire list without finding a spot, it means all values are equal, so we can insert anywhere.
prev to head and curr to head.next. Use a flag toInsert to track when we find the insertion point.prev.val <= insertVal <= curr.val, we found a normal insertion point between two nodes.prev.val > curr.val, we're at the tail-to-head boundary. Insert here if insertVal >= prev.val (new maximum) or insertVal <= curr.val (new minimum).prev and curr and return head.class Solution:
def insert(self, head: 'Node', insertVal: int) -> 'Node':
if head == None:
newNode = Node(insertVal, None)
newNode.next = newNode
return newNode
prev, curr = head, head.next
toInsert = False
while True:
if prev.val <= insertVal <= curr.val:
# Case #1.
toInsert = True
elif prev.val > curr.val:
# Case #2. where we locate the tail element
# 'prev' points to the tail, i.e. the largest element!
if insertVal >= prev.val or insertVal <= curr.val:
toInsert = True
if toInsert:
prev.next = Node(insertVal, curr)
# mission accomplished
return head
prev, curr = curr, curr.next
# loop condition
if prev == head:
break
# Case #3.
# did not insert the node in the loop
prev.next = Node(insertVal, curr)
return headWhere is the size of the list.
Only checking for normal insertion between two nodes (prev.val <= insertVal <= curr.val) without handling the wraparound point where the largest value connects to the smallest. At this boundary, the new value might be a new maximum (greater than tail) or new minimum (smaller than head), both of which should be inserted at this location.
When all nodes in the circular list have the same value, neither the normal insertion condition nor the boundary condition will ever be true. Without a fallback case that inserts the node after completing a full traversal, the algorithm loops forever. The solution must detect when it returns to the starting node without inserting.
When the head is null, failing to create a self-referential node (where node.next = node) results in either a null pointer exception or an incorrectly formed list. The empty list case must create a new node that points to itself to maintain the circular property.