算法day06

112 阅读2分钟

1.已知二叉树中的两个节点O1 ,O2,找出他们的最低公共祖先节点

方法一:遍历整棵树,用HashMap存储每个节点的父节点;将O1的所有祖先节点存在HashSet中,再遍历O2所有的祖先节点,每次判断O2当前祖先节点是否在HashSet中,找到了直接返回该祖先节点

public static TreeNode FindLowestParentsNodes(TreeNode o1, TreeNode o2, TreeNode head) {
    HashMap<TreeNode, TreeNode> map = new HashMap<>();
    Poccess(head, map);
    HashSet<TreeNode> set = new HashSet<>();
    map.put(head, head);
    TreeNode cur = o1;
    while (cur != map.get(cur)) {
        set.add(cur);
        cur = map.get(cur);

    }
    cur = o2;
    while (!set.contains(cur) && cur!=map.get(cur)) {
        cur = map.get(cur);
    }
    return cur;
}


public static void Poccess(TreeNode root, HashMap<TreeNode, TreeNode> map) {
    if (root == null) return;
    map.put(root.left, root);
    map.put(root.right, root);
    Poccess(root.left, map);
    Poccess(root.right, map);
}

方法二:有两种情况1.有一个节点是另一个的祖先节点2.两个节点分别在最低公共祖先的左子树和右子树上。只需要遇到o1或o2的时候返回他自己,递归的收集左树和右树上的信息。子树返回o1,o2或者null,当左树和右树返回值都不为null,说明当前节点是最低公共祖先,只需要将当前节点返回到最上层。如果两子树返回值一个为空一个不为空,返回不为空的那个,直到传递到最上层。

public static TreeNode FindLowestParentsNodes1(TreeNode head,TreeNode o1,TreeNode o2){
    if(head==null || head==o1 || head==o2) return head;
    TreeNode left = FindLowestParentsNodes1(head.left, o1, o2);
    TreeNode right = FindLowestParentsNodes1(head.right, o1, o2);

    if(left!=null && right!=null) return head;

    return left!=null?left:right;
}

2.对包含parent指针指向其父节点的二叉树,给定二叉树其中一个节点,返回其后继节点

public static TreeNode getSuccessor(TreeNode node){


    //node有右树,后继节点为node右树上最左的节点
    if(node.right!=null){
        node = node.right;
        while (node.left!=null){
            node = node.left;
        }
        return node;
    }else {//node无右树
        while (node.parent!=null && node.parent.left!=node  ){//判断是否为node.parent的左孩子,如果不是继续往上找
            node = node.parent;
        }
        return node.parent;
    }

}

3.序列化和反序列化二叉树

//按照先序序列化二叉树
public static String SerialByPre(TreeNode root) {
    if (root == null) return "#_";
    String res = root.val + "_";
    res += SerialByPre(root.left);
    res += SerialByPre(root.right);
    return res;
}

//按照先序反序列化
public static TreeNode reconByPreString(String s) {
    String[] val = s.split("_");
    Queue<String> queue = new LinkedList<>();
    for (int i = 0; i < val.length; i++) {
        queue.add(val[i]);
    }
    return reconByPre(queue);
}

public static TreeNode reconByPre(Queue<String> queue) {
    if(queue.isEmpty()) return null;
    String s = queue.poll();
    if (s == "#") return null;
    TreeNode node = new TreeNode(Integer.valueOf(s));
    node.left = reconByPre(queue);
    node.right = reconByPre(queue);
    return node;
}