Uber面试题2 | House Robber III
来源:互联网 发布:手机怎么设置淘宝预售 编辑:程序博客网 时间:2024/05/22 01:49
题目描述
小偷找到了一个新的偷盗地点,这里地区的房子组成了一棵二叉树,地区的入口是二叉树的根所在的房子。如果小偷同时偷窃了两个直接相邻的房子,就会触发警报器。求在不触发警报器的情况下小偷可以抢到的最多的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 ¬_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为总房子数
- Uber面试题2 | House Robber III
- Uber面试题1 | 房屋窃贼 House Robber II
- House Robber III
- House Robber III
- LeetCode House Robber III
- House Robber III
- LeetCode337. House Robber III
- [LeetCode] House Robber III
- 337. House Robber III
- 337. House Robber III
- leetcode---House Robber III
- 《leetCode》:House Robber III
- 337. House Robber III
- 337. House Robber III
- [LeetCode]House Robber III
- 337. House Robber III
- 337. House Robber III
- [leetcode] House Robber III
- Mac重装系统、win7双系统以及多分区
- 打印100-999以内的水仙花数
- java基础学习总结——GUI编程(一)
- Android getResources()方法
- java批量插入数据到Oracle
- Uber面试题2 | House Robber III
- PHP学习笔记——面向对象编程
- linux svn和web同步
- jJMeter UDP Request:不等待服务器响应
- 关于安装Samba的过程及其遇到的一些问题
- C++11多线程编程 call_once
- mysql 使用 workbench工具【E-R图 <--> 数据库】之间相互转换
- Android蓝牙开发浅谈
- liunx 服务器时间和本地时间不匹配