题目链接:LeeCode213打家劫舍Ⅲ
题目描述:
这题看了Leetcode大神liweiwei1419的题解,感觉自己还是太菜了,其实这题原理跟打家劫舍Ⅰ,Ⅱ是一模一样的,但是可能由于我对树的理解有点浅,所以自己写了一个没跑过去。然后说说这题的思路
思路
新了解一个词叫后效性,虽然已经做了好几个类似的题了,我竟然也是看了题解才知道股票类型的题和这个还有打家劫舍都是一种题型。那下面说一下什么叫后效性。
后效性:
我理解的后效性就是当前状态会影响之后的状态,使得后面的状态不确定
所以一般有后效性的题都要消除后效性,那么怎么消除后效性?加一维数组,可以实现状态之间的互相转换,即消除后效性,使问题变得无后效性。
然后开始说这道题的思想:
为了消除后效性,我们选择对一个节点选择两种状态,头还是不偷,偷时候的最大利益表示为dp[0],不偷时候的最大利益表示为dp[1],那么一个节点当时的利益就是两种情况:
1.偷:该节点偷的时候就不能偷该节点的子节点,所以该节点的利润=左节点不偷状态的最大利润+右节点不偷状态的最大利润+加自己本身的利润
2.不偷:当前不偷的时候子节点偷不偷随便,所以该节点的利润=左节点偷与不偷最大值+有节点偷与不偷最大值
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int rob(TreeNode root) {
int[] treedp = treedp(root);
return Math.max(treedp[0],treedp[1] );
}
public static int[] treedp(TreeNode root){
//当找到底的时候开始回溯
if(root==null) return new int[]{
0,0};
//存左节点利润的数组
int[] left=treedp(root.left);
//存右节点利润的数组
int[] right=treedp(root.right);
int[] cur=new int[2];
//当前节点不偷的情况
cur[0]= Math.max(left[0],left[1])+Math.max(right[0],right[1]);
//当前节点偷的时候
cur[1]= left[0]+right[0]+root.val;
return cur;
}
}