树形dp套路使用前提:

如果题目求解目标是S规则,则求解流程可以定成以每一个节点为头节点的子树在S规则下的每一个答案,并且最终答案一定在其中
树形dp套路第一步:
以某个节点X为头节点的子树中,分析答案有哪些可能性,并且这种分析是以X的左子树、X的右子树和X整棵树的角度来考虑可能性的
树形dp套路第二步:
根据第一步的可能性分析,列出所有需要的信息
树形dp套路第三步:
合并第二步的信息,对左树和右树提出同样的要求,并写出信息结构
树形dp套路第四步:
设计递归函数,递归函数是处理以X为头节点的情况下的答案。包括设计递归的basecase,默认直接得到左树和右树的所有信息,以及把可能性做整合,并且要返回第三步的信息结构这四个小步骤

二叉树节点间的最大距离问题

从二叉树的节点a出发,可以向上或者向下走,但沿途的节点只能经过一次,到达节点b时路径上的节点个数叫作a到b的距离,那么二叉树任何两个节点之间都有距离,求整棵树上的最大距离。

  1. public class MaxDistanceInTree {
  2. public static class Node {
  3. public int value;
  4. public Node left;
  5. public Node right;
  6. public Node(int data) {
  7. this.value = data;
  8. }
  9. }
  10. public static int maxDistance(Node head) {
  11. int[] record = new int[1];
  12. return posOrder(head, record);
  13. }
  14. public static class ReturnType{
  15. public int maxDistance;
  16. public int h;
  17. public ReturnType(int m, int h) {
  18. this.maxDistance = m;;
  19. this.h = h;
  20. }
  21. }
  22. // 返回以x为头的整棵树,两个信息
  23. public static ReturnType process(Node head) {
  24. if(head == null) {
  25. return new ReturnType(0,0);
  26. }
  27. ReturnType leftReturnType = process(head.left);
  28. ReturnType rightReturnType = process(head.right);
  29. int includeHeadDistance = leftReturnType.h + 1 + rightReturnType.h;
  30. int p1 = leftReturnType.maxDistance;
  31. int p2 = rightReturnType.maxDistance;
  32. int resultDistance = Math.max(Math.max(p1, p2), includeHeadDistance);
  33. int hitself = Math.max(leftReturnType.h, leftReturnType.h) + 1;
  34. return new ReturnType(resultDistance, hitself);
  35. }
  36. public static int posOrder(Node head, int[] record) {
  37. if (head == null) {
  38. record[0] = 0;
  39. return 0;
  40. }
  41. int lMax = posOrder(head.left, record);
  42. int maxfromLeft = record[0];
  43. int rMax = posOrder(head.right, record);
  44. int maxFromRight = record[0];
  45. int curNodeMax = maxfromLeft + maxFromRight + 1;
  46. record[0] = Math.max(maxfromLeft, maxFromRight) + 1;
  47. return Math.max(Math.max(lMax, rMax), curNodeMax);
  48. }
  49. public static void main(String[] args) {
  50. Node head1 = new Node(1);
  51. head1.left = new Node(2);
  52. head1.right = new Node(3);
  53. head1.left.left = new Node(4);
  54. head1.left.right = new Node(5);
  55. head1.right.left = new Node(6);
  56. head1.right.right = new Node(7);
  57. head1.left.left.left = new Node(8);
  58. head1.right.left.right = new Node(9);
  59. System.out.println(maxDistance(head1));
  60. Node head2 = new Node(1);
  61. head2.left = new Node(2);
  62. head2.right = new Node(3);
  63. head2.right.left = new Node(4);
  64. head2.right.right = new Node(5);
  65. head2.right.left.left = new Node(6);
  66. head2.right.right.right = new Node(7);
  67. head2.right.left.left.left = new Node(8);
  68. head2.right.right.right.right = new Node(9);
  69. System.out.println(maxDistance(head2));
  70. }
  71. }

派对的最大快乐值

image.png

public class MaxHappy {

    public static int maxHappy(int[][] matrix) {
        int[][] dp = new int[matrix.length][2];
        boolean[] visited = new boolean[matrix.length];
        int root = 0;
        for (int i = 0; i < matrix.length; i++) {
            if (i == matrix[i][0]) {
                root = i;
            }
        }
        process(matrix, dp, visited, root);
        return Math.max(dp[root][0], dp[root][1]);
    }

    public static void process(int[][] matrix, int[][] dp, boolean[] visited, int root) {
        visited[root] = true;
        dp[root][1] = matrix[root][1];
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[i][0] == root && !visited[i]) {
                process(matrix, dp, visited, i);
                dp[root][1] += dp[i][0];
                dp[root][0] += Math.max(dp[i][1], dp[i][0]);
            }
        }
    }

    public static void main(String[] args) {
        int[][] matrix = { { 1, 8 }, { 1, 9 }, { 1, 10 } };
        System.out.println(maxHappy(matrix));
    }
}