leetcode 1028. 从先序遍历还原二叉树【DFS】

典型的二叉树问题首先都可以想到用遍历树的方式完成。遍历的方式有DFS和BFS,题中传入的字符串是先序遍历的结果,显然应该用DFS来实现二叉树的还原。
本题的难点在于从字符串获取每个结点对应的深度以及通过深度来找到该节点对应的父亲结点。不论是用递归或者非递归的方法实现,这两部分的代码思想都是一致的。

  1. 方法一
    使用栈来实现非递归的DFS算法,将节点入栈,栈的深度就代表了栈顶元素所代表的的节点对应的深度。因此当栈的长度大于遍历到的节点深度时,表明遍历到的节点的父亲结点不是栈顶元素,需要将栈中元素出栈并通过栈的大小找到对应的父亲节点。
class Solution {
    public TreeNode recoverFromPreorder(String S) {
        Stack<TreeNode> st = new Stack<>();
        TreeNode head= null;
        for(int i=0; i<S.length();){
            int curLevel = 0;
            while(i < S.length() && S.charAt(i)=='-'){
                i++;
                curLevel++;
            }
            int start = i;
            while(i < S.length() && S.charAt(i)!= '-'){
                i++;
            }
            TreeNode cur = new TreeNode(Integer.parseInt(S.substring(start, i)));
            if(st.size()==0){
                head = cur;
                st.push(cur);
                continue;
            }
            while(st.size()>curLevel){
                st.pop();
            }
            if(!st.isEmpty()){
                if(st.peek().left != null){
                    st.peek().right = cur;
                }else{
                    st.peek().left = cur;
                }
                st.push(cur);        
            }                                        
        }
        return head;
    }
}
  1. 方法二
    使用递归的方式,需要定义一个实例域来记录字符串的遍历下标。
    树的深度通过在递归函数中传入变量并每次递归+1实现深度的记录,在通过该深度与被遍历的节点的深度进行比较判断遍历到的节点是否是上一层递归中的节点的儿子节点,若是,则优先左子节点后右子节点的顺序进入下一步递归,否则返回上一次递归。
class Solution {
    int index;
    public TreeNode recoverFromPreorder(String S) {
        index=0;
        return helper(S, 0);
    }
        
    public TreeNode helper(String S, int depth){
        if(index >=S.length()){
            return null;
        }
        int curDepth = 0;
        int k = index;
        while(k<S.length() && S.charAt(k)=='-' ){
            curDepth++;
            k++;
        }
        if (curDepth != depth) return null;
        index = k;
        while(k<S.length() && S.charAt(k) != '-'){
            k++;
        }
        int val = Integer.parseInt(S.substring(index, k));
        index = k;
        TreeNode cur = new TreeNode(val);
        cur.left = helper(S, depth+1);
        cur.right = helper(S, depth+1);
        return cur;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值