LeetCode 426. Convert binary search tree to ordered double linked list

Keywords: Oracle

A binary search tree is locally transformed into a sorted bi-directional circular list. The left and right child pointers can be used as the precursor and successor pointers of the bidirectional circular list.

To give you a better understanding of the problem, take the following binary search tree as an example:

We want to transform this binary search tree into a two-way circular list. Each node in the list has a predecessor and successor pointer. For a bidirectional circular list, the first node is preceded by the last node, and the last node is followed by the first node.

The following figure shows the linked list transformed from the above binary search tree. "head" refers to the node with the smallest element in the linked list.

In particular, we want to be able to do the transformation in place. After the conversion, the left pointer of the node in the tree needs to point to the precursor, and the right pointer of the node in the tree needs to point to the successor. You also need to return a pointer to the first node in the list.

The following figure shows the transformed binary search tree. The solid line represents the successor relationship and the dotted line represents the precursor relationship.

Algorithm: we know that the two-way linked list returned is in order, so we need to use the middle order traversal of BST. We first recurse the entire left subtree, then the entire right subtree. It should be noted that the successor node of the rightmost node of the left subtree is the root node, while the predecessor node of the leftmost node of the right subtree is the root node. In order to deal with this relationship, we use pair to store nodes. Finally, don't forget to recycle.

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
public:
    pair<Node*, Node*>dfs(Node* root){
        if(!root->left&&!root->right)return {root,root};
        if(root->left&&root->right){
            auto ls=dfs(root->left), rs=dfs(root->right);
            ls.second->right=root,root->left=ls.second;
            rs.first->left=root,root->right=rs.first;
            return {ls.first, rs.second};
        }
        if(root->left){
            auto ls=dfs(root->left);
            ls.second->right=root,root->left=ls.second;
            return {ls.first, root};
        }
        if(root->right){
            auto rs=dfs(root->right);
            rs.first->left=root,root->right=rs.first;
            return {root, rs.second};
        }
        return {root,root};
    }
    Node* treeToDoublyList(Node* root) {
        if(!root)return NULL;
        auto side=dfs(root);
        side.first->left=side.second;
        side.second->right=side.first;
        return side.first;
    }
};

Posted by euph on Wed, 30 Oct 2019 22:13:58 -0700