1028. 从先序遍历还原二叉树

Posted zjpaang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1028. 从先序遍历还原二叉树相关的知识,希望对你有一定的参考价值。

1028. 从先序遍历还原二叉树

题目分析

这个题其实跟我们之前序列化二叉树的题有点类似,这个题的难点在于怎么把对应的层次节点的父节点找出来,说实话想的有点久。
因为树的问题一般都是递归解决,所以我这次也是用了递归的方法。
具体来说就是

  • 字符串的第一次出现的数字必定为当前树的根节点,因为他是前序遍历。
  • 我们可以依赖一个标记来记录当前所要找的层次。
  • 因为这个是一棵二叉树,所以每次只需要分成左子树和右子树即可。
  • 另外题目说了优先构建左子树,所以我们在实现的时候也要注意这个点。

代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    /**
     * 说实话代码写的挺烂的,不过AC了
     * @param S
     * @return
     */
    public TreeNode recoverFromPreorder(String S) {
        //处理空字符串
        if(S.length() == 0){
            return null;
        }
        return helper(S,1);
    }

    public TreeNode helper(String str, int level){
        //如果字符串为空,说明这边已经不存在节点了,直接返回空
        if(str.length() == 0){
            return null;
        }
        int j = 0;
        int num =  0;
        //处理根节点,因为根据题目的描述,我们的值可能不止一位,所以要逐个计算第一个数的数值
        while(j < str.length() && str.charAt(j) != ‘-‘){
            num = num * 10 + Integer.parseInt(String.valueOf(str.charAt(j)));
            j++;
        }
        //创建根节点
        TreeNode root = new TreeNode(num);
        //这个是关键,我们定义一个指针,它的值为第一个数字结束的下标加当前的层数+1
        //例如 1-2-5 我们第一个数字结束的下标是0当前层数为1,所以我们开始遍历的下标应该为0+1+1。
        int i = j+level;
        //我们采用分治法思想,每次都把字符串分成左子树和右子树来进行处理。
        String left = "";
        String right = "";
        int count = 0;
        //记录左边界
        int lastIndex = i;
        while(i < str.length() - 1){
            //统计-出现的次数,当-出现的次数与层数相等,并且接下来的字符不是-,说明我们已经找到了右子树开始的下标
            if(str.charAt(i) == ‘-‘){
                count++;
            }else{
                count = 0;
            }
            //在这里进行切割,要注意substring是左闭右开的
            if(count == level && str.charAt(i+1) != ‘-‘){
                left = str.substring(lastIndex,i-level+1);
                right = str.substring(i+1);
                break;
            }
            i++;
        }
        //因为题目说明优先建立左子树,如果我们遍历整棵树都找不到右子树,说明剩余的字符串都是左子树
        //这里要注意还需要判断lastIndex是否小于字符串长度,否则会有字符串越界问题
        if(i >= str.length() - 1 && lastIndex < str.length()){
            left = str.substring(lastIndex);
        }
        //递归建立左子树和右子树
        root.left = helper(left,level+1);
        root.right = helper(right,level+1);
        //返回根节点
        return root;
    }
}

总结

这个题也不是很难,主要是考一种思维吧,不过最近做题的手感真的是越来越差了,这个题起码花了半个小时才写出来,哭了



以上是关于1028. 从先序遍历还原二叉树的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1028. 从先序遍历还原二叉树

leetcode——1028.从先序遍历还原二叉树

leetcode1028. 从先序遍历还原二叉树

leetcode1028. 从先序遍历还原二叉树

leetcode1028. 从先序遍历还原二叉树

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