LeetCode刷题——从前序与中序遍历序列构造二叉树#105#Medium

从前序与中序遍历序列构造二叉树题目的思路探讨与源码
    从前序与中序遍历序列构造二叉树的题目如下图,该题属于树结构和递归类型的题目,主要考察对于树本身结构以及遍历的理解和认识。本文的题目作者想到2种方法,第一种方法是迭代法,第二种方法是递归方法。其中第一种方法使用java写、第二种方法使用Python写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
在这里插入图片描述
    本人认为该题目可以使用迭代法和递归法,首先来说迭代法。我们观察初始特殊情况,当前序遍历或者中序遍历只要有一个是空的时候,直接返回结果是空,程序结束。而当它们都不为空的时候,我们把前序遍历的第一个元素,也就是整个树的根节点记录下来。然后创建一个放置树节点的列表,把根节点放到列表里面,并初始化下标为0,开始从前序结果里进行遍历,拿出队列里的结果,如果当前节点的根节点和中序遍历的结果不一致,则把前序遍历的结果赋值给当前节点的左子树,并放到列表里;否则的话就把列表里的值弹出,并把前序遍历的结果赋值给当前节点的右子树,按这个方法循环遍历,直到前序结果被遍历完毕,那么按照这个思路我们的代码如下:

#喷火龙与水箭龟
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder==null || preorder.length==0) {
            return null;
        }
        TreeNode node = new TreeNode(preorder[0]);
        Deque<TreeNode> stackList = new LinkedList<TreeNode>();
        stackList.push(node);
        int flag = 0;
        for (int ir=1;ir<preorder.length;ir++) {
            int preFlag = preorder[ir];
            TreeNode vex = stackList.peek();
            if (vex.val != inorder[flag]) {
                vex.left = new TreeNode(preFlag);
                stackList.push(vex.left);
            }
            else{
                while (! stackList.isEmpty() && stackList.peek().val == inorder[flag]) {
                    vex = stackList.pop();
                    flag=flag+1;
                }
                vex.right = new TreeNode(preFlag);
                stackList.push(vex.right);
            }
        }
        return node;
    }
}

在这里插入图片描述
    显然,我们还可以使用递归的方法来进行解决,首先判断前序遍历是否为空,如果是则直接返回空,程序结束。否则的话,把前序遍历的第一个节点记录,就是根节点。并且将根节点通过索引反向定位出根节点在中序结果的下标,记录为flag,然后通过调用当前函数去得到左子树和右子树的结果,直到最终某一轮的前序结果是空则结束。所以根据这个思路就可以写出代码,下面是Python代码部分:

#喷火龙与水箭龟
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if(len(inorder)==0):
            return None
        node=TreeNode(preorder[0])
        flag=inorder.index(preorder[0])
        node.left = self.buildTree(preorder[1:flag+1], inorder[:flag])
        node.right = self.buildTree(preorder[flag+1:], inorder[flag+1:])
        return node

在这里插入图片描述
    从结果来说java版本的迭代方法还不错,python版本的递归算法速度就不太好,应该是可以进一步提速的,希望朋友们能够多多指教,非常感谢。

Guess you like

Origin blog.csdn.net/qq_26727101/article/details/117536303