337_house_robber_III
来源:互联网 发布:淘宝店铺数据统计表 编辑:程序博客网 时间:2024/05/16 09:17
LeetCode 337 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.
解题思路
强烈推荐这个讨论帖,解释非常详细。
文章第一种方法是通用的递归方法,分两种情况讨论:如果包括根,则结果为根的值和孙子树(子树的子树)的结果之和;如果不包括根,则结果为左右子树结果之和。最后返回两种情况的最大者。这种方法的问题在于有很多重复的计算,计算根结点的时候需要子树,孙子树,然而,在计算子树的时候需要计算子树的子树,而这已经在根结点中已经计算过了,造成重复计算。
文章第二种方法则是为了解决第一个方法的不足,引入hash表保存子树计算结果,避免重复计算。
文章第三种方法其实也是沿用方法一思路,分情况讨论,比较关键的是递归同时返回包含根结点和不包含根结点两种情况下的结果,如果将函数拆开递归是不能实现的。相比方法一,该方法比较明确第区分了两种不同的情况,避免重复计算;相比于方法二,思路更清晰,更简洁。
代码
源码链接:https://github.com/lilingyu/337_house_robber_III
#include <iostream>#include <stdlib.h>#include <vector>#include <stdio.h>using namespace std;struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {}};/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution{ private: vector<int> robSub(TreeNode* root){ if(NULL == root){ return vector<int>(2,0); } vector<int> left = robSub(root->left); vector<int> right = robSub(root->right); printf("root:\t%d\n", root->val); printf("left:\t%d\t%d\n", left[0], left[1]); printf("right:\t%d\t%d\n\n", right[0], right[1]); vector<int> res(2,0); res[0] = max(left[0], left[1]) + max(right[0], right[1]); res[1] = root->val + left[0] + right[0]; return res; } public: int rob(TreeNode* root){ vector<int> result = robSub(root); return max(result[0], result[1]); } }; int main() { Solution solt;#if 0 /*case 0: 4 /\ 1 NULL /\ 2 NULL /3 */ TreeNode* root = new TreeNode(4); root->left = new TreeNode(1); root->left->left = new TreeNode(2); root->left->left->left = new TreeNode(3);#endif // 0#if 1/*case 1: 2 /\ 1 3 \ 4*/ TreeNode* root = new TreeNode(2); root->left = new TreeNode(1); root->right = new TreeNode(3); root->left->left = new TreeNode(4);#endif // 1 cout<<solt.rob(root); return 0; }
- 337_house_robber_III
- 337APuzzles
- ocp-337
- Codeforces #337
- 337HouseRobberIII
- 337C
- 337BRoutine Problem
- codeforces 337C Quiz
- codeforces---#196 337A
- codeforces--#196 337B
- Codeforces 337d
- 337C - Quiz
- cf-337C Quiz
- 电子产品发起“337调查”
- CodeForces 337A Puzzles
- Codeforence 337A Puzzles
- CodeForces 337A - Puzzles
- OCP-V13-337
- Android控件架构与自定义控件详解(四)——事件拦截机制分析
- [POJ2262]Goldbach's Conjecture
- asp.net 学习记录3
- 如何使用Apktool
- 如何在不影响原有aapt源码的情况下编译定制版aapt
- 337_house_robber_III
- 百度之星——Problem D
- Gson的使用
- 报错:GenerateSource 任务意外失败:未将对象引用设置到对象的实例
- maven--私服的搭建(Nexus的使用)
- Cookie
- Docker的另外15个命令
- 高精度加法——一步一步算法篇
- utilities(matlab)—— 合成数据(synthesis data)