树
头结点没有父亲 其他节点只有一个父亲的有向无环图,直观理解为发散状
在树上,从头结点出发到任何节点的路径是唯一的,不管是二叉树还是多叉树
树型dp是指在树上做动态规划,依赖关系比一般的动态规划简单
因为绝大部分都是父依赖子
套路
1 分析父树得到答案需要子树的哪些信息
2 把子树信息的全集定义成递归返回值
3 通过递归让子树返回全集信息
4 整合子树的全集信息得到父树的全集信息并且返回
题目一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
public static int largestBSTSubtree(TreeNode root) { return f(root).maxBstSize; }
public static class Info { public long max; public long min; public boolean isBst; public int maxBstSize;
public Info(long a, long b, boolean c, int d) { max = a; min = b; isBst = c; maxBstSize = d; } }
public static Info f(TreeNode x) { if (x == null) { return new Info(Long.MIN_VALUE, Long.MAX_VALUE, true, 0); } Info infol = f(x.left); Info infor = f(x.right); long max = Math.max(x.val, Math.max(infol.max, infor.max)); long min = Math.min(x.val, Math.min(infol.min, infor.min)); boolean isBst = infol.isBst && infor.isBst && infol.max < x.val && x.val < infor.min; int maxBSTSize; if (isBst) { maxBSTSize = infol.maxBstSize + infor.maxBstSize + 1; } else { maxBSTSize = Math.max(infol.maxBstSize, infor.maxBstSize); } return new Info(max, min, isBst, maxBSTSize); }
|
题目二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
public static int maxSumBST(TreeNode root) { return f(root).maxBstSum; }
public static class Info { public int max; public int min; public int sum; public boolean isBst; public int maxBstSum;
public Info(int a, int b, int c, boolean d, int e) { max = a; min = b; sum = c; isBst = d; maxBstSum = e; } }
public static Info f(TreeNode x) { if (x == null) { return new Info(Integer.MIN_VALUE, Integer.MAX_VALUE, 0, true, 0); } Info infol = f(x.left); Info infor = f(x.right); int max = Math.max(x.val, Math.max(infol.max, infor.max)); int min = Math.min(x.val, Math.min(infol.min, infor.min)); int sum = infol.sum + infor.sum + x.val; boolean isBst = infol.isBst && infor.isBst && infol.max < x.val && x.val < infor.min; int maxBstSum = Math.max(infol.maxBstSum, infor.maxBstSum); if (isBst) { maxBstSum = Math.max(maxBstSum, sum); } return new Info(max, min, sum, isBst, maxBstSum); }
|
题目三
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public static int diameterOfBinaryTree(TreeNode root) { return f(root).diameter; }
public static class Info { public int diameter; public int height;
public Info(int a, int b) { diameter = a; height = b; }
}
public static Info f(TreeNode x) { if (x == null) { return new Info(0, 0); } Info leftInfo = f(x.left); Info rightInfo = f(x.right); int height = Math.max(leftInfo.height, rightInfo.height) + 1; int diameter = Math.max(leftInfo.diameter, rightInfo.diameter); diameter = Math.max(diameter, leftInfo.height + rightInfo.height); return new Info(diameter, height); }
|
题目四
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public static int distributeCoins(TreeNode root) { return f(root).move; }
public static class Info { public int cnt; public int sum; public int move;
public Info(int a, int b, int c) { cnt = a; sum = b; move = c; } }
public static Info f(TreeNode x) { if (x == null) { return new Info(0, 0, 0); } Info infol = f(x.left); Info infor = f(x.right); int cnts = infol.cnt + infor.cnt + 1; int sums = infol.sum + infor.sum + x.val; int moves = infol.move + infor.move + Math.abs(infol.cnt - infol.sum) + Math.abs(infor.cnt - infor.sum); return new Info(cnts, sums, moves); }
|