zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    

    总结

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

  • 相关阅读:
    FTP服务总结
    编译安装hpptd2.4
    搭建DNS服务
    定制简单的Linux系统
    建立私有CA
    关于/boot文件的修复实验
    shell脚本进阶(二)
    datetime模块日期转换和列表sorted排序
    linux操作命令
    Python 中的特殊双下划线方法
  • 原文地址:https://www.cnblogs.com/ZJPaang/p/13156166.html
Copyright © 2011-2022 走看看