TS写二叉树相关判断(三)

给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点

情况拆分:
1、o1和o2互为最低公共祖先(o1是o2的祖先或o2是o1的祖先)
2、o1和o2不互为祖先,有第三个节点作为最低公共祖先。


    /**
     * 给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点
     * 情况拆分:1、o1和o2互为最低公共祖先(o1是o2的祖先或o2是o1的祖先)
     *          2、o1和o2不互为祖先,有第三个节点作为最低公共祖先。 
     * 
     * 方法一:递归遍历二叉树节点,用哈希结构map,存入每个节点的父节点。数组1记录node1向上的节点链。
     * 然后由o2依次向上取节点,查看数组1中是否存在,第一个存在的即为最低公共祖先节点
     */
    lowestCommonAncestor(head:TNode,o1:TNode,o2:TNode){
        let map = new Map<TNode,TNode>();
        map.set(head,head)
        this.process(head,map);
        let list1 = [];
        let cur = o1;
        while(map.get(cur) != head){
            list1.push(map.get(cur));
            cur = map.get(cur);
        }
        list1.push(head);

        cur = o2;
        while(map.get(cur) != head){
            if(list1.indexOf(map.get(cur)) != -1) return map.get(cur);
            cur = map.get(cur);
        }
        return head;
    }

    process(head:TNode,map:Map<TNode,TNode>){
        if(head == null) return;
        map.set(head.left,head);
        map.set(head.right,head);
        this.process(head.left,map);
        this.process(head.right,map);
    }

    /**
     * 方法二:
     */
    lowestCommonAncestor1(head:TNode,o1:TNode,o2:TNode) {
        if(head == null || head == o1 || head == o2) return head;
        let left = this.lowestCommonAncestor1(head.left,o1,o2);
        let right = this.lowestCommonAncestor1(head.right,o1,o2);
        if(left != null && right != null) return head;
        
        return left != null ? left : right;
    }

现有一种特殊结构的二叉树节点,该节点包含指向父节点的指针parent。

在此种二叉树中找到一个节点的后继节点(中序遍历中该节点的后一个节点)
情况拆分:
1、该节点有右子树,其后继节点为其右子树的左子树上的叶节点。
2、该节点无右子树,其后继节点为其祖先中 最低处的为左子树的节点的 父节点。
分析:parent指针可以简化求后继节点的算法时间复杂度,从O(N) 简化成两个节点之间的距离K。

	/**
     * 现有一种特殊结构的二叉树节点,该节点包含指向父节点的指针parent。
     * 在此种二叉树中找到一个节点的后继节点(中序遍历中该节点的后一个节点)
     * 
     * 情况拆分:1、该节点有右子树,其后继节点为其右子树的左子树上的叶节点。
     *          2、该节点无右子树,其后继节点为其祖先中 最低处的为左子树的节点的 父节点。
     */
    getSuccessorNode(node:TNode1){
        if(node == null) return null;
        if(node.right != null) return this.getLeftMost(node.right);
        else return this.getLeftAncestor(node.parent);
    }

    /**
     * 拿到左子树的叶节点
     */
    getLeftMost(node:TNode1){
        if(node.left == null) return node; 
        this.getLeftMost(node.left);
    }

二叉树先序序列化和反序列化

	/**
     * 二叉树先序序列化
     */
    treeSerialPreOrder(head:TNode){
        if(head == null) return "#_";
        let res = head.value + "_";
        res += this.treeSerialPreOrder(head.left);
        res += this.treeSerialPreOrder(head.right);
        return res;
    }

    reconTree(strs:string){
        let list = strs.split("_");
        return this.reconPreOrder(list);  
    }

    /**
     * 二叉树先序反序列化
     * @param list 
     * @returns 
     */
    reconPreOrder(list:string[]){
        let str = list.pop();
        if(str == "#") return;

        let node = new TNode();
        node.value = parseInt(str);
        node.left = this.reconPreOrder(list);
        node.right = this.reconPreOrder(list);
        return node;
    }

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值