Leetcode337:打家劫舍三(!!!树型动态规划!!!)
总结树的三种遍历:
1 //先序遍历 2 void PreOrder(TreeNode root) { 3 if(root == null){ 4 return; 5 } 6 System.out.println("树的先序遍历:执行对根节点的操作"); 7 PreOrder(root.left); 8 PreOrder(root.right); 9 } 10 11 //中序遍历 12 void Inthread(TreeNode root) { 13 if(root == null){ 14 return; 15 } 16 Inthread(root.left); 17 System.out.println("树的中序遍历:执行对根节点的操作"); 18 Inthread(root.right); 19 } 20 21 //后序遍历 22 void PostOrder(TreeNode root) { 23 if(root == null){ 24 return; 25 } 26 PostOrder(root.left); 27 PostOrder(root.right); 28 System.out.println("树的后序遍历:执行对根节点的操作"); 29 }
337. 打家劫舍 III
维护两个动态规划表f(node) 和g(node),其中f(node)表示偷node节点可以获得的最大金额,g(node)表示不偷node节点可以获得的最大金额
则如果偷node节点,则最大金额等于不偷node.left和不偷node.right可获得的最大金额之和,即f(node)=g(node.left)+g(node.right);
如果不偷node节点,则最大金额等于左子树的最大金额和右子树的最大金额之和,左子树的最大金额等于max(f(node.left),g(node.left)),右子树的最大金额等于max(f(node.right), g(node.right)),因此g(node) = max(f(node.left),g(node.left)) + max(f(node.right), g(node.right))
最后整棵树可获得的最大金额等于max(f(root),g(root))
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 Mapf = new HashMap (); //表示偷当前节点TreeNode,可以获得的最大金额Integer 18 Map g = new HashMap ();//表示不偷当前节点TreeNode,可以获得的最大金额Integer 19 20 //主方法 21 public int rob(TreeNode root) { 22 //后续遍历这棵树,填写两个表格 23 dfs(root); 24 //最后整棵树可获得的最大金额等于max(f(root),g(root)) 25 return Math.max(f.getOrDefault(root,0), g.getOrDefault(root,0)); 26 } 27 28 //树的深度遍历,在遍历过程中,填动态规划的表f和g 29 public void dfs(TreeNode root){ 30 if(root == null){ 31 return; 32 } 33 dfs(root.left); 34 dfs(root.right); 35 //填两个表 36 f.put(root,root.val + g.getOrDefault(root.left, 0) + g.getOrDefault(root.right, 0));//偷当前节点 37 g.put(root,Math.max(f.getOrDefault(root.left,0), g.getOrDefault(root.left,0)) + Math.max(f.getOrDefault(root.right,0), g.getOrDefault(root.right,0)));//不偷当前节点 38 } 39 }