给定两个二叉树的节点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;
}