《leetCode》:House Robber III

题目

The thief has found himself a new place for his thievery again. 
There is only one entrance to this area, called the "root." 
Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree".
 It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:
     3
    / \
   2   3
    \   \ 
     3   1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
     3
    / \
   4   5
  / \   \ 
 1   3   1
Maximum amount of money the thief can rob = 4 + 5 = 9.

思路:看错题目

原以为是相邻层之间不能选择,于是就有 了如下的代码。

/* * 借助两个队列来完成按层来取出树节点。 * */
    public int rob(TreeNode root) {
        if(root==null){
            return 0;
        }
        if(root.left==null&&root.right==null){//只有一层
            return root.val;
        }
        Queue<TreeNode> q1=new LinkedList<TreeNode>();
        Queue<TreeNode> q2=new LinkedList<TreeNode>();
        q1.add(root);
        List<Integer> res=new ArrayList<Integer>();
// res.add(root.val);
        while(!q1.isEmpty()){
            int maxValue=0;
            while(!q1.isEmpty()){
                TreeNode node=q1.poll();
                maxValue+=node.val;
                if(node.left!=null){
                    q2.add(node.left);
                }
                if(node.right!=null){
                    q2.add(node.right);
                }
            }
            //开始将这一层节点的和 与上面的倒数第2层和倒数第3层可能产生的最大值。
            int len=res.size();
            if(len<2){//第一层和第二层的节点和直接进入即可
                res.add(maxValue);
            }
            else if(len==2){
                maxValue+=res.get(len-2);
                res.add(maxValue);
            }
            else if(len>=3){
                maxValue+=Math.max(res.get(len-2),res.get(len-3));
                res.add(maxValue);
            }
// q1.addAll(q2);
// q2.clear();
            while(!q2.isEmpty()){
                q1.add(q2.poll());
            }
        }

        return Math.max(res.get(res.size()-1), res.get(res.size()-2));
    }

思路

思路来源于:https://leetcode.com/discuss/95367/1ms-java-solution

解释如下:此题就是利用动态规划来做,当前节点产生的最大值要么是此节点参与后产生的,要么是此节点没有参与产生的。

实现代码如下:

public int rob(TreeNode root) {
        int []maxValue=robHelper(root);
        return Math.max(maxValue[0], maxValue[1]);
    }
    /* * 返回的数组长度为2,第一个存储的是 * */
    private int[] robHelper(TreeNode root) {
        if(root==null){
            return new int[]{0,0};
        }
        //maxValue[0]用来存储根节点没有参与的最大值,而maxValue[1]则是存储这根节点参与了产生的最大值。
        int[] maxValue=new int[2];
        int[] leftMaxValue=robHelper(root.left);
        int[] rightMaxValue=robHelper(root.right);
        maxValue[0]=Math.max(leftMaxValue[1], leftMaxValue[0])+Math.max(rightMaxValue[1], rightMaxValue[0]);
        maxValue[1]=root.val+leftMaxValue[0]+rightMaxValue[0];//既然root参与了,则root的左右节点就不能参与了。
        return maxValue;
    }

你可能感兴趣的:(LeetCode,house,Robber)