See all coding puzzles and patterns here.
- Leetcode 426 (Premium)
- Difficulty: Medium
- Patterns:
Problem Definition
Given a binary search tree (BST), convert it to a doubly-linked list, with each element's previous reference pointing to the next lesser element and its next reference pointing to the next greater element.
Node and Item Classes
Below are the Node
and Item
classes that will represent nodes in the input BST
and the items in the output doubly-linked list.
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
class Item:
def __init__(self, value, prev=None, nxt=None):
self.value = value
self.prev = prev
self.nxt = nxt
Example
For this binary tree:
4
/ \
2 6
/ \ / \
1 3 5 8
/ / \
0 7 9
The resulting doubly-linked list should be:
| |->| |->| |->| |->| |->| |->| |->| |->| |->| |
return pointer->|0| |1| |2| |3| |4| |5| |6| |7| |8| |9|
| |<-| |<-| |<-| |<-| |<-| |<-| |<-| |<-| |<-| |
Solution
This is a graph traversal problem that can best be solved with a depth-first traversal.
def helper(root: Node) -> tuple[Item, Item]:
"""
Return (least Item, greatest Item)
"""
item = Item(root.value)
if root.left is None:
least = item
else:
least, prev = helper(root.left)
prev.nxt = item
item.prev = prev
if root.right is None:
greatest = item
else:
nxt, greatest = helper(root.right)
nxt.prev = item
item.nxt = nxt
return least, greatest
def convert_bst_to_dl_list(root: Node) -> Item:
return helper(root)[0]
Complexity
Let $n = $ the number of nodes in the BST.
Since we are visiting every node only once, the runtime complexity should be $\Theta(n)$.
At some points, we might have $2 \cdot log(n)$ stack frames in our program stack; so the auxiliary space complexity should be $O(log(n))$.