Uber面试题2 | House Robber III

19 篇文章 0 订阅

题目描述 

小偷找到了一个新的偷盗地点,这里地区的房子组成了一棵二叉树,地区的入口是二叉树的根所在的房子。如果小偷同时偷窃了两个直接相邻的房子,就会触发警报器。求在不触发警报器的情况下小偷可以抢到的最多的money。

Example:

     3
/ \
2 3
\ \
3 1

小偷可以抢到的最多的money是3+3+1=7(偷窃带下划线的房子)

算法分析

本题是House Robber的follow up。House Robber-i中房子排列成一个序列,House Robber-ii中房子排列成一个环,均可以用动态规划解决。

这里简单分析一下房子排成一个序列的情况,直觉上我们应该尽量偷价值高的房子,但因为有限制条件不能偷相邻的房子,直接贪心不可行。考虑动态规划,如果我们已知前k个房子可能偷到的最高价值,当k等于n时我们也就得到了全局最优解;同时,前k个房子能偷到的最高价值可以通过对第k个房子做决策(偷或者不偷),从比k小的局部最优解中得到。

对于本问题,由于是树上的问题, 我们有一种dp类型是,在树上一边搜索,一边利用dp数组保存状态,所以我们叫他树形dp,这是一类型大家没怎么见过的新题型。假设我们已知了根节点的左右子树的局部最优解,通过对根节点所在的房子进行决策:偷或者不偷,我们就可以得到全局最优解。具体算法过程如下: 递归先求得左右子树的局部最优解,分别表示该子树根节点的房子偷和不偷所能得到的最高价值,再得到了左右子树的返回值后,对于本层更新,我们需要考虑,1.左右儿子不偷的时候我们当前可以偷本层,2.左右儿子都偷的时候我们当前本层则不能偷。

具体动态规划四要素为:

Definition:
dp[i][0]表示以i为根的子树不偷根节点能获得的最高价值,dp[i][1]表示以i为根的子树偷根节点能获得的最高价值

Function:
dp[i][0] = max(dp[left[i]][0], dp[left[i]][1]) + max(dp[right[i]][0], dp[right[i]][1]);
dp[i][1] = dp[left[i]][0] + dp[right[i]][0];

Intialize: 

空节点的dp值均为0

Answer: 
dp[root][0]和dp[root][1]中的较大值

最后返回根节点的两个dp值中较大的那个即可。


/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * }
 */
class Solution {
private:
    void visit(TreeNode* root, int &rob, int &not_rob) {
        rob = not_rob = 0;
        if (root == NULL)
            return;
            
        int left_rob, left_not_rob, right_rob, right_not_rob;
        visit(root->left, left_rob, left_not_rob);
        visit(root->right, right_rob, right_not_rob);
        
        rob = left_not_rob + right_not_rob + root->val;
        not_rob = max(left_rob, left_not_rob) + max(right_rob, right_not_rob);
    }
public:
    /**
     * @param root: The root of binary tree.
     * @return: The maximum amount of money you can rob tonight
     */
    int houseRobber3(TreeNode* root) {
        // write your code here
        int rob, not_rob;
        visit(root, rob, not_rob);
        return max(rob, not_rob);
    }
};

面试官角度分析

本题可以用搜索解决,但面试官考察的是对树和动态规划的理解。给出基于动态规划思想的O(n)可达到hire的程度,n为总房子数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值