Question
Consider a simple node-like data structure called BiNode, which has pointers to two other nodes.
public class BiNode {
public BiNode node1, node2;
public int data;
}
The data structure BiNode could be used to represent both a binary tree (where node1 is the left node and node2 is the right node) or a doubly linked list (where node1 is the previous node and node2 is the next node). Implement a method to convert a binary search tree (implemented with BiNode) into a doubly linked list. The values should be kept in order and the operation should be performed in place (that is, on the original data structure).
Solution
At another post [LeetCode Plus] Convert BST to Circular DLL, we already discussed 2 approaches:
- in-order traversal approach
- divide and conquer approach
First approach isn’t intuitive. We will further discuss D&C approach here.
The key of the solution is how we return both HEAD and TAIL. The book suggests 3 ways:
- Build a data structure to store both head and tail
- Just return head, and retrieve tail by traversing thru - bad time complexity O(n^2)
- Use circular linked-list! Time O(n).
I wrote the code for 1st and 2nd approach. And 3rd is already covered in previous post.
- You need to understand why we need the list to be circular.
Code
Approach 1
public static BiNode convert(BiNode root) {
BiNodePair res = helper(root);
return res.leftMost;
}
private static BiNodePair helper(BiNode node) {
if (node == null) {
return null;
}
BiNodePair res = new BiNodePair(node, node);
if (node.node1 != null) {
BiNodePair leftRes = helper(node.node1);
res.leftMost = leftRes.leftMost;
leftRes.rightMost.node2 = node;
node.node1 = leftRes.rightMost;
}
if (node.node2 != null) {
BiNodePair rightRes = helper(node.node2);
res.rightMost = rightRes.rightMost;
rightRes.leftMost.node1 = node;
node.node2 = rightRes.leftMost;
}
return res;
}
static class BiNodePair {
BiNode leftMost;
BiNode rightMost;
public BiNodePair(BiNode node1, BiNode node2) {
leftMost = node1;
rightMost = node2;
}
}
Approach 2
public static BiNode convert(BiNode root) {
if (root == null) {
return null;
}
return helper(root);
}
private static BiNode helper(BiNode node) {
// node is not null
BiNode newHead = node;
// do left part
if (node.node1 != null) {
newHead = helper(node.node1);
BiNode leftTail = getListTail(newHead);
leftTail.node2 = node;
node.node1 = leftTail;
}
// do right part
if (node.node2 != null) {
BiNode rightHead = helper(node.node2);
node.node2 = rightHead;
rightHead.node1 = node;
}
return newHead;
}
private static BiNode getListTail(BiNode head) {
// head is not null
while (head.node2 != null) {
head = head.node2;
}
return head;
}