[Medium] 708. Insert into a Sorted Circular Linked List
Difficulty: Medium
Category: Linked List, Circular List
Companies: Amazon, Facebook, Google, Microsoft
Given a circular linked list, represented by a Node class, insert a new value into the list while maintaining the circular and sorted order of the list.
The list is circular, so the last node points back to the first node. The list is sorted in ascending order.
Examples
Example 1:
Input: head = [3,4,1], insertVal = 2
Output: [3,4,1,2]
Explanation: Insert 2 between 1 and 3, maintaining the circular sorted order.
Example 2:
Input: head = [], insertVal = 1
Output: [1]
Explanation: Create a circular list with a single node.
Example 3:
Input: head = [1], insertVal = 0
Output: [1,0]
Explanation: Insert 0 between 1 (tail) and 1 (head), wrapping around.
Constraints
- The number of nodes in the list is in the range
[0, 5 * 10^4] -10^6 <= Node.val, insertVal <= 10^6- List is sorted in ascending order
- List is circular
Solution Approaches
Approach 1: One-Pass Insertion (Recommended)
Key Insight: Traverse the circular list once and look for a valid insertion point. Handle edge cases at the wrap-around point.
Algorithm:
- Handle empty list by creating a self-referencing node
- Traverse the circular list
- Find insertion point where
curr->val <= insertVal && curr->next->val >= insertVal - Handle wrap-around case where
curr->next->val < curr->val(wrap point)- Insert if
insertVal >= curr->valORinsertVal <= curr->next->val
- Insert if
- If no valid point found after full traversal, insert after current position
Time Complexity: O(n) where n is the number of nodes
Space Complexity: O(1)
# Definition for a Node.
class Node:
def __init__(self, _val: int = 0, _next: 'Node | None' = None):
self.val = _val
self.next = _next
class Solution:
def insert(self, head: 'Node', insertVal: int) -> 'Node':
# Empty list case
if not head:
newNode = Node(insertVal)
newNode.next = newNode
return newNode
curr = head
while True:
# Case 1: Normal position
if curr.val <= insertVal <= curr.next.val:
break
# Case 2: Wrap-around point (max -> min)
if curr.val > curr.next.val:
if insertVal >= curr.val or insertVal <= curr.next.val:
break
curr = curr.next
# Case 3: Completed full loop (all values same or no spot found)
if curr == head:
break
# Insert new node
newNode = Node(insertVal, curr.next)
curr.next = newNode
return head
Solution Explanation
Approach: Iterative pointer walk (this problem)
Key idea: Difficulty:** Medium
How the code works: Difficulty: Medium Category: Linked List, Circular List
- Draw pointers before rewriting links.
- Dummy head simplifies insert/delete at the head.
- Slow/fast pointers find middle or detect cycles in one pass.
Walkthrough — input head = [3,4,1], insertVal = 2, expected output [3,4,1,2]:
Insert 2 between 1 and 3, maintaining the circular sorted order.
Implementation Details
Empty List Handling
class Solution:
def insert(self, head: 'Node', insertVal: int) -> 'Node':
if not head:
newNode = Node(insertVal)
newNode.next = newNode
return newNode
# Step 1: Find the maximum node
maxNode = head
curr = head.next
while curr != head:
if curr.val >= maxNode.val:
maxNode = curr
curr = curr.next
# Step 2: Insert at wrap-around (max → min)
if insertVal >= maxNode.val or insertVal <= maxNode.next.val:
newNode = Node(insertVal, maxNode.next)
maxNode.next = newNode
return head
# Step 3: Insert in normal sorted position
curr = maxNode.next # smallest node
while curr.next.val < insertVal:
curr = curr.next
newNode = Node(insertVal, curr.next)
curr.next = newNode
return head
Normal Insertion Case
class Solution:
def insert(self, head: 'Node', insertVal: int) -> 'Node':
newNode = Node(insertVal)
# Case 1: Empty list
if not head:
newNode.next = newNode
return newNode
curr = head
while True:
# Case 2: Normal insertion
if curr.val <= insertVal <= curr.next.val:
break
# Case 3: Wrap-around point
if curr.val > curr.next.val and (
insertVal >= curr.val or insertVal <= curr.next.val
):
break
curr = curr.next
# Case 4: Full loop (all values same)
if curr == head:
break
# Insert node
newNode.next = curr.next
curr.next = newNode
return head
Wrap-Around Insertion Case
if not head:
new_node = Node(insertVal)
new_node.next = new_node # Self-referencing
return new_node
Edge Cases
- Empty List: Create a circular list with single node
- Single Node: Insert anywhere (trivially maintains order)
- All Same Values: Insert at any position
- Insert at Head: Special care needed for wrap logic
- Insert Largest Value: Should go after maximum node
- Insert Smallest Value: Should go before minimum node
Follow-up Questions
- What if the list is not guaranteed to be sorted?
- How would you handle duplicate insertion values?
- What if you need to insert multiple values at once?
- How would you delete a value from a circular list?
Common Mistakes
- Skipping edge cases (empty input, single element, boundaries).
- Off-by-one errors in loops and index ranges.
- Forgetting to handle the case when no valid answer exists.
Related Problems
- LC 23: Swap Nodes in Pairs - Linked list manipulation
- LC 25: Reverse Nodes in k-Group - Linked list reversal
- LC 141: Linked List Cycle - Detect cycle in linked list
- LC 708: Insert into Sorted Circular List (This problem)
Optimization Techniques
- Single Pass: Most efficient with O(n) time
- Early Exit: Return immediately after insertion
- Edge Case Handling: Handle empty list, single node separately
- Wrap Detection: Identify wrap point by comparing adjacent values
Code Quality Notes
- Readability: Clear variable names and logic separation
- Correctness: Handles all edge cases properly
- Performance: Optimal O(n) time complexity
- Memory: O(1) space complexity
Key Takeaways
- Pattern: Iterative pointer walk (this problem)
- Difficulty:** Medium
- Category:** Linked List, Circular List
References
- LC 708: Insert into a Sorted Circular Linked List on LeetCode
- LeetCode Discuss — LC 708: Insert into a Sorted Circular Linked List
- LeetCode Editorial (may require premium)
Template Reference
Thinking Process
Difficulty: Medium
Category: Linked List, Circular List
- Draw pointers before rewriting links.
- Dummy head simplifies insert/delete at the head.
- Slow/fast pointers find middle or detect cycles in one pass.
Common Approaches
Typical techniques for this pattern:
| Approach | Time | Space | Notes |
|---|---|---|---|
| Iterative pointer walk (this problem) | O(n) | O(1) | Traversal, insertion |
| Dummy head node | O(n) | O(1) | Simplify head-edge cases |
| Reversal (3-pointer) | O(n) | O(1) | Reverse sublist or full list |
| Slow/fast pointers | O(n) | O(1) | Middle, cycle, merge lists |