[leetcode]114. Flatten Binary Tree to Linked List

题目链接:114. Flatten Binary Tree to Linked List
Given a binary tree, flatten it to a linked list in-place.
Hints:
If you notice carefully in the flattened tree, each node’s right child points to the next node of a pre-order traversal.

对于这道题目,我们发现其二叉树编程的链表中的每一个结点的子结点就是对这棵树进行先序遍历中该结点的下一个结点。所以这道题的思路也一定和先序遍历有关。(二叉树的遍历)。
根据二叉树先序遍历的算法,我们知道最靠左的一排子结点是在先序遍历中最先被访问的结点,也就是该题要求生成的链表中最靠前的结点。所以我们如果需要朝右生成链表的话,就需要先将左右子树互换并递归这一过程,这样最靠左的一排结点就会被放在正确的位置上。
除去原题目要求的向右构造的链表之外,我还补充了向左构造链表的代码。

具体思路请看代码及注释:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void flatten(TreeNode root) {
        flattenfunction(root);
    }

    /*
    This method flattens a binary tree and constructs it into a linked list in the right subtree
    @param current root used for the flatten function
    @return the tree node that is the last one in the right subtree
    */
    private TreeNode flattenfunction(TreeNode root){
        if (root == null){
            return root;
        }
        if (root.left != null){
            //since we have to construct the binary tree in the order of pre-order traversal and we know that the left most nodes in the tree are always the nodes that are visited firstly (as the pre-order traversal algorithm like), so we just switch the left subtree of every level in the left subtree of the original root into the right side and recurse this process.
            //after this process, we have move every left most nodes into the right place of the linked list 
            //switch left and right subtree
            TreeNode temp = root.right;
            root.right = root.left;
            root.left = temp;
        }
        if (root.right != null){
            //While there are nodes in the right subtree(after switch), we'll recurse the process with the right child as the root parameter. //While there is no left child on this node, we can return the last node safely because without left subtree there can't be any nodes that can be switched to right subtree which make the right subtree deeper
            //If there still is left subtree, we switch it to the right subtree of the last node and recurse the process. At the same time, we let the left subtree of the root to be null
            //Node last stores the last node in the right subtree
            TreeNode last = flattenfunction(root.right);
            if (root.left == null){
                return last;
            }

            last.right = root.left;
            root.left = null;

            return flattenfunction(last.right);
        }
        //if both left and right are null, then current root should be the last one.
        return root;
    }

    /*
    this method returns a linked list that is constructed on the left subtree of every node.
    */
    private TreeNode leftflatten(TreeNode root){
        if (root == null){
            return root;
        }
        if (root.left != null){
            //we return the last node by recursion
            TreeNode last = leftflatten(root.left);
            if (root.right != null){
                //if there still exists a right subtree, we make it to be the left child of the last node and make the right child of the to be null
                last.left = root.right;
                root.right = null;
                return leftflatten(last.left);
            }
            else {
                return last;
            }
        }
        if (root.right != null ){
            //while root.left == null and root.right != null, we just switch the right subtree to the left subtree and execute the process.
            root.left = root.right;
            root.right = null;
            return leftflatten(root.left);
        }

        //while both left and right child of the root is null, we know it should be the leaf node(last node) and return it
        return root;
    }
}

你可能感兴趣的:(LeetCode)