二叉树的递归套路——二叉树的最大距离

简介: 二叉树的递归套路——二叉树的最大距离

【题目2】

给定一颗二叉树的头结点head,任何两个结点之间都存在距离,返回整颗二叉树的最大距离image.pngimage.png

package com.harrison.class08;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Code02_MaxDistance {
  public static class Node {
    public int value;
    public Node left;
    public Node right;
    public Node(int data) {
      this.value = data;
    }
  }
  public static class Info {
    public int maxDistance;
    public int height;
    public Info(int m, int h) {
      maxDistance = m;
      height = h;
    }
  }
  public static int maxDistance1(Node head) {
    return process1(head).maxDistance;
  }
  public static Info process1(Node head) {
    if (head == null) {
      return new Info(0, 0);
    }
    Info leftInfo = process1(head.left);
    Info rightInfo = process1(head.right);
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    int maxDistance = Math.max(
        Math.max(leftInfo.maxDistance, rightInfo.maxDistance),
        leftInfo.height + rightInfo.height + 1);
    return new Info(maxDistance, height);
  }
  public static int maxDistance2(Node head) {
    if (head == null) {
      return 0;
    }
    ArrayList<Node> arr = getPrelist(head);
    HashMap<Node, Node> parentMap = getParentMap(head);
    int max = 0;
    for (int i = 0; i < arr.size(); i++) {
      for (int j = i; j < arr.size(); j++) {
        max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j)));
      }
    }
    return max;
  }
  public static ArrayList<Node> getPrelist(Node head) {
    ArrayList<Node> arr = new ArrayList<>();
    fillPrelist(head, arr);
    return arr;
  }
  public static void fillPrelist(Node head, ArrayList<Node> arr) {
    if (head == null) {
      return;
    }
    arr.add(head);
    fillPrelist(head.left, arr);
    fillPrelist(head.right, arr);
  }
  public static HashMap<Node, Node> getParentMap(Node head) {
    HashMap<Node, Node> map = new HashMap<>();
    map.put(head, null);
    fillParentMap(head, map);
    return map;
  }
  public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
    if (head.left != null) {
      parentMap.put(head.left, head);
      fillParentMap(head.left, parentMap);
    }
    if (head.right != null) {
      parentMap.put(head.right, head);
      fillParentMap(head.right, parentMap);
    }
  }
  public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) {
    HashSet<Node> o1Set = new HashSet<>();
    Node cur = o1;
    o1Set.add(cur);
    while (parentMap.get(cur) != null) {
      cur = parentMap.get(cur);
      o1Set.add(cur);
    }
    cur = o2;
    while (!o1Set.contains(cur)) {
      cur = parentMap.get(cur);
    }
    Node lowestAncestor = cur;
    cur = o1;
    int distance1 = 1;
    while (cur != lowestAncestor) {
      cur = parentMap.get(cur);
      distance1++;
    }
    cur = o2;
    int distance2 = 1;
    while (cur != lowestAncestor) {
      cur = parentMap.get(cur);
      distance2++;
    }
    return distance1 + distance2 - 1;
  }
  public static Node generateRandomBST(int maxLevel, int maxValue) {
    return generate(1, maxLevel, maxValue);
  }
  public static Node generate(int level, int maxLevel, int maxValue) {
    if (level > maxLevel || Math.random() < 0.5) {
      return null;
    }
    Node head = new Node((int) (Math.random() * maxValue));
    head.left = generate(level + 1, maxLevel, maxValue);
    head.right = generate(level + 1, maxLevel, maxValue);
    return head;
  }
  public static void main(String[] args) {
    int maxLevel = 4;
    int maxValue = 100;
    int testTimes = 1000000;
    for (int i = 0; i < testTimes; i++) {
      Node head = generateRandomBST(maxLevel, maxValue);
      if (maxDistance1(head) != maxDistance2(head)) {
        System.out.println("Oops!");
      }
    }
    System.out.println("finish!");
  }
}
相关文章
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
57 0
|
算法
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
57 0
|
机器学习/深度学习 存储 人工智能
代码随想录训练营day21| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先...
代码随想录训练营day21| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先...
|
机器学习/深度学习 算法 Java
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...
剑指offer_二叉树---树的子结构
剑指offer_二叉树---树的子结构
61 0
【创作赢红包】< 二叉树OJ题(一) >单值二叉树&&二叉树的最大深度&&翻转二叉树&&相同的树&&对称二叉树
【创作赢红包】< 二叉树OJ题(一) >单值二叉树&&二叉树的最大深度&&翻转二叉树&&相同的树&&对称二叉树
Leetcode1302–层数最深叶子结点的和(深搜/递归)
Leetcode1302–层数最深叶子结点的和(深搜/递归)
每日三题-二叉树的层序遍历、二叉树的中序遍历、最小覆盖子串
每日三题 二叉树的层序遍历 二叉树的中序遍历 最小覆盖子串
103 1
每日三题-二叉树的层序遍历、二叉树的中序遍历、最小覆盖子串
代码随想录刷题|LeetCode 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数(上)
代码随想录刷题|LeetCode 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数
代码随想录刷题|LeetCode 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数(下)
代码随想录刷题|LeetCode 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数