Skip to content

added houseRobberIII #106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LeetCode

| # | Title | Solution | Difficulty |
|---| ----- | -------- | ---------- |
|337|[House Robber III](https://leetcode.com/problems/house-robber-iii/) | [C++](./algorithms/cpp/houseRobber/houseRobberIII.cpp)|Medium|
|334|[Increasing Triplet Subsequence](https://leetcode.com/problems/increasing-triplet-subsequence/) | [C++](./algorithms/cpp/increasingTripletSubsequence/increasingTripletSubsequence.cpp)|Medium|
|330|[Patching Array](https://leetcode.com/problems/patching-array/) | [C++](./algorithms/cpp/patchingArray/PatchingArray.cpp)|Medium|
|329|[Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/) | [C++](./algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp)|Medium|
Expand Down
88 changes: 88 additions & 0 deletions algorithms/cpp/houseRobber/houseRobberIII.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Source : https://leetcode.com/problems/house-robber-iii/
// Author : Calinescu Valentin
// Date : 2016-04-29

/***************************************************************************************
*
* 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.
* Credits:
* Special thanks to @dietpepsi for adding this problem and creating all test cases.
*
***************************************************************************************/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/*
* Solution 1 - O(N log N)
* =========
*
* We can use a recursive function that computes the solution for every node of the tree
* using the previous solutions calculated for the left and right subtrees. At every step
* we have 2 options:
*
* 1) Take the value of the current node + the solution of the left and right subtrees of
* each of the left and right children of the current node.
* 2) Take the solution of the left and right subtrees of the current node, skipping over
* its value.
*
* This way we can make sure that we do not pick 2 adjacent nodes.
*
* If we implemented this right away we would get TLE. Thus, we need to optimize the
* algorithm. One key observation would be that we only need to compute the solution for
* a certain node once. We can use memoization to calculate every value once and then
* retrieve it when we get subsequent calls. As the header of the recursive function
* doesn't allow additional parameters we can use a map to link every node(a pointer) to
* its solution(an int). For every call the map lookup of an element and its insertion
* take logarithmic time and there are a constant number of calls for each node. Thus, the
* algorithm takes O(N log N) time to finish.
*
*/
class Solution {
public:
map<TreeNode*, int> dict;
int rob(TreeNode* root) {
if(root == NULL)
return 0;
else if(dict.find(root) == dict.end())
{
int lwith = rob(root->left);
int rwith = rob(root->right);
int lwithout = 0, rwithout = 0;
if(root->left != NULL)
lwithout = rob(root->left->left) + rob(root->left->right);
if(root->right != NULL)
rwithout = rob(root->right->left) + rob(root->right->right);
//cout << lwith << " " << rwith << " " << lwithout << " " << rwithout << '\n';
dict[root] = max(root->val + lwithout + rwithout, lwith + rwith);
}
return dict[root];
}
};