分析:
事实证明我想简单了,还是要针对每个结点(及其左右)的情况来列举情况取最大。
找出二叉树中最大的不相邻结点的值的和
题意:
一开始的想法是用一个布尔型参数确定下一个结点的值取不取,想的是就两种情况,一层取,下一层就不去...:
private void helper(TreeNode node, boolean b){
if(node == null){
return;
}
if(b == true){
sum += node.val;
helper(node.left, false);
helper(node.right, false);
}else{
helper(node.left, true);
helper(node.right, true);
}
}
事实证明我想简单了,还是要针对每个结点(及其左右)的情况来列举情况取最大。
这样就是一个动态规划的问题:对于一个子问题:
一个结点和它的左右子节点,如果取这个结点那么这个结点为根的值就应该是这个结点的值加上左子节点(为根)不取的值再加上右子节点(为根)不取的值。如果不取这个结点,就是取这个结点的左子节点和不取这个结点的左子节点的更大值和取这个结点的右结点或不取这个结点的右结点的值的更大值的和。
而对于一个结点为根的值就是以上两种情况的更大值。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int rob(TreeNode root) {
int[] max = dp(root);
return Math.max(max[0], max[1]);
}
public int[] dp(TreeNode root) {
if (root == null) {
return new int[]{0, 0};
}
int[] max = new int[2];//max[0] 是不取当前结点的值,max[1]是取当前结点的值
int[] leftMax = dp(root.left);
int[] rightMax = dp(root.right);
max[0] = Math.max(leftMax[0], leftMax[1]) + Math.max(rightMax[0], rightMax[1]);
max[1] = leftMax[0] + rightMax[0] + root.val;
return max;
}
}
小结:动态规划就是要具有一般化研究子问题的想法。
(将一个结点看做一棵子树的根。它取或不取,取的话左右子节点就不能取,不取的话,左右子节点可取可不取,这个时候的每个结点都代表它为根的树。)