关于树的反序列化

写在前面

二叉树的序列化和反序列化相对简单,常用的方式是前序遍历和层序遍历,见 leetcode 第297题 https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

前缀表示父子关系

1.奇怪的树

一棵树

// 这棵树 序列化之后 前序遍历序列化
var str = '01010101010101010201020102010104010401010402';

2.反序列化这棵树

// 定义节点
static class SNode{
        public String val;
        public List<SNode> child = new ArrayList<SNode>();

        public SNode(String val){
            this.val = val;
        }
    }
// 定义节点

/**
     * 
     * @param str  须反序列化的字符串
     * @param section 下个节点所在层级应具有的长度,认为根节点所在层级节点长度为 sec
     * @param sec 每sec个长度表示一个层级,比如第一级节点值长度为sec,第二层级节点值长度则为sec+sec,第三层层级节点值长度为sec+sec+sec 
     * @param parent 表示该节点的父亲 (重要)
     * @return
     */
static cnt = 0;  //作为数组指针
public static SNode serial(String str,int section,int sec,String parent){
        if(cnt+section>str.length()){
            return null;
        }
        if(parent!=null && !str.substring(cnt,cnt+section).startsWith(parent)){

            return null;
        }
        String par = str.substring(cnt,cnt+=section);
        SNode root = new SNode(par);

        while(cnt<str.length()){
            SNode child = serial(str,section+sec,sec,par);
            if(child!=null){
                root.child.add(child);
            }else{
                break;
            }
        }
        return root;
    }
// main函数
public static void main(String[] args) {
        String str = "01010101010101010201020102010104010401010402";
        //这里初始section 为 2;
        //层级增量sec 为 2
        SNode node = serial(str,2,2,null); //
        System.out.println(node);
    }

3 一道题

在这里插入图片描述
该解法为深度优先搜索,解题关键在于input格式的理解,能通过split将input分割,导致节点与节点的父子关系通过 "\t"的数量维系,最最关键的是对于叶子节点的判断

public int lengthLongestPath(String input) {
        String[] arr = input.split("\n");
        while(cnt<arr.length){
           dfs(arr,0,0);
        } 
        return r;
    }

    int cnt = 0; 
    int r = 0;
    public boolean dfs(String[] arr,int v,int res){
        if(cnt>=arr.length){
            return true;
        }
        if(getCount(arr[cnt])!=v){
            return true;
        }       
        if(cnt<arr.length&&arr[cnt].contains(".")){   
            int len = arr[cnt].length() - getCount(arr[cnt]);
            cnt++;
            r = Math.max(r,len + res);
            return false;
        }       
        res+= arr[cnt].length() - getCount(arr[cnt]);
        cnt++;
        while(cnt<arr.length){
            if(dfs(arr,v+1,res+1)){
                break;
            }
        }       
        return false;    
    }

    public static int getCount(String str){
        int count = 0;
        for(int i = 0;i<str.length();i++){
            if(str.charAt(i)=='\t'){
                count++;
            }else{
                break;
            }
        }
        return count;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值