Prerequisites
Before attempting this problem, you should be comfortable with:
- Linked List Traversal - Iterating through nodes using next pointers to find specific elements
- Sentinel/Dummy Node Pattern - Using a placeholder node before the head to simplify edge cases like inserting at the beginning
- Carry Propagation - Understanding how addition works digit by digit, where trailing 9s become 0s and carry forward
1. Sentinel Head + Textbook Addition
Intuition
When adding one to a number, the only digits that change are trailing nines (which become zeros) and the rightmost non-nine digit (which increments by one). If all digits are nines, we need an extra digit at the front.
By using a sentinel node before the head, we handle the case where a new digit is needed (like 999 becoming 1000) without special logic. We simply find the rightmost non-nine digit, increment it, and set all following digits to zero.
Algorithm
- Create a sentinel node with value
0and point its next to the head. - Traverse the list to find the rightmost node that is not
9, storing a reference to it. - Increment that node's value by
1. - Set all nodes after it to
0(these were all9s that now carry over). - If the sentinel's value became
1(meaning we needed an extra digit), return the sentinel. Otherwise, return its next node.
class Solution:
def plusOne(self, head: ListNode) -> ListNode:
# sentinel head
sentinel = ListNode(0)
sentinel.next = head
not_nine = sentinel
# find the rightmost not-nine digit
while head:
if head.val != 9:
not_nine = head
head = head.next
# increase this rightmost not-nine digit by 1
not_nine.val += 1
not_nine = not_nine.next
# set all the following nines to zeros
while not_nine:
not_nine.val = 0
not_nine = not_nine.next
return sentinel if sentinel.val else sentinel.nextTime & Space Complexity
- Time complexity:
- Space complexity:
Where is the length of the input list
Common Pitfalls
Forgetting the All-Nines Case
When all digits are 9 (e.g., 9 -> 9 -> 9), adding one requires a new node at the front. Without a sentinel node or explicit handling, you may return a result missing the leading 1, producing 0 -> 0 -> 0 instead of 1 -> 0 -> 0 -> 0.
Processing Left-to-Right Instead of Right-to-Left
Unlike arrays, singly linked lists cannot be traversed backwards. Naively incrementing from the head ignores how addition propagates carries from the least significant digit. This leads to incorrect results when carries need to cascade through multiple nodes.
Not Tracking the Rightmost Non-Nine Node
The key insight is that only trailing nines become zeros, and the rightmost non-nine digit increments. Failing to track this node forces you to either reverse the list or use recursion, both adding unnecessary complexity or space overhead.