House Robber I & II & III

House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example

Given [3, 8, 4], return 8.

分析:

因为“偷”第一个或者“偷”第二个对后面的选择是有影响的,所以从后往前推算更好。

total[i] = Math.max(A[i] + total[i + 2], total[i + 1]);

A[i] + total[i + 2] 指的是偷第i家。

total[i + 1] 指的是不偷i家。

 1 public class Solution {
 2     /**
 3      * @param A: An array of non-negative integers.
 4      * return: The maximum amount of money you can rob tonight
 5      */
 6     public long houseRobber(int[] A) {
 7           if (A == null || A.length == 0) return 0;
 8           if (A.length == 1) return A[0];
 9           if (A.length == 2) return Math.max(A[0], A[1]);
10
11           long[] total = new long[A.length];
12           int length = total.length;
13           total[length - 1] = A[length - 1];
14           total[length - 2] = Math.max(A[length - 1], A[length - 2]);
15
16           for (int i = length - 3; i >= 0; i--) {
17               total[i] = Math.max(total[i + 2] + A[i], total[i + 1]);
18           }
19           return total[0];
20     }
21 }

House Robber II

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example

nums = [3,6,4], return 6.

分析:

现在是一个环了,感觉好像找不到起始点。其实反过来想,就是头尾不能同时选而已。所以我们分别选取两个不同的起始点和结束点,跑两次就可以了。

 1 public class Solution {
 2     /**
 3      * @param nums: An array of non-negative integers.
 4      * return: The maximum amount of money you can rob tonight
 5      */
 6     public int houseRobber2(int[] nums) {
 7         if (nums == null || nums.length == 0) return 0;
 8         if (nums.length == 1) return nums[0];
 9         return Math.max(getMax(nums, 0, nums.length - 2), getMax(nums, 1, nums.length - 1));
10     }
11
12     public int getMax(int[] nums, int start, int end) {
13         if (start == end) return nums[start];
14         if (start + 1 == end) return Math.max(nums[start], nums[end]);
15
16         int[] total = new int[end - start + 1];
17         total[0] = nums[start];
18         total[1] = Math.max(nums[start], nums[start + 1]);
19
20         for (int i = start + 2; i <= end; i++) {
21             total[i - start] = Math.max(nums[i] + total[i - start - 2], total[i - start - 1]);
22         }
23         return total[total.length - 1];
24     }
25 }

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

  3
 / 2   3
 \   \
  3   1

Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

    3
   /   4   5
 / \   \
1   3   1

Maximum amount of money the thief can rob = 4 + 5 = 9.

分析:

看到树,想都不用多想,立马想到递归。关键是这个递归怎么写啊?

既然我们不知道是否把root包含进去是否是最优,那么我们就创建一个函数,返回一个数组,这个数组包含两种情况下的最大值。

 1 /**
 2  * Definition of TreeNode:
 3  * public class TreeNode {
 4  *     public int val;
 5  *     public TreeNode left, right;
 6  *     public TreeNode(int x) { val = x; }
 7  * }
 8  */
 9 public class Solution {
10     /**
11      * @param root: The root of binary tree.
12      * @return: The maximum amount of money you can rob tonight
13      */
14     public int houseRobber3(TreeNode root) {
15         if(root == null)
16         return 0;
17
18         int[] result = maxTotal(root);
19         return Math.max(result[0], result[1]);
20     }
21
22     public int[] maxTotal(TreeNode root){
23         if(root == null){
24             int[] result = {0, 0};
25             return result;
26         }
27
28         int[] result = new int[2];
29         int[] left = maxTotal(root.left);
30         int[] right = maxTotal(root.right);
31
32         // result[0] is when root is selected, result[1] is when not.
33         result[0] = root.val + left[1] + right[1];
34         result[1] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
35
36         return result;
37     }
38 }
时间: 2024-08-07 04:34:12

House Robber I & II & III的相关文章

解题思路:house robber i &amp;&amp; ii &amp;&amp; iii

这系列题的背景:有个小偷要偷钱,每个屋内都有一定数额的钱,小偷要发家致富在北京买房的话势必要把所有屋子的钱都偷了,但是屋子之内装了警报器,在一定条件下会触发朝阳群众的电话,所以小偷必须聪明一点,才能保证偷到的钱最多. 问题i:这些屋子排成一排,连续两家失窃就会触发朝阳群众电话 问题ii:这些屋子两成一个圈(四合院既视感),连续两家失窃就会触发朝阳群众电话 问题iii:这些屋子组成一棵树,有连接的两个节点同时失窃就会触发朝阳群众电话 i: 思路:一道典型的dp问题,dp[i]表示在小偷路过第i间房

hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用

3081 题意: n个女孩选择没有与自己吵过架的男孩有连边(自己的朋友也算,并查集处理),2分图,有些边,求有几种完美匹配(每次匹配每个点都不重复匹配) 我是建二分图后,每次增广一单位,(一次完美匹配),再修改起点还有终点的边流量,继续增广,直到达不到完美匹配为止.网上很多是用二分做的,我觉得没必要...(网上传播跟风真严重...很多人都不是真正懂最大流算法的...) 3277 : 再附加一条件,每个女孩可以最多与k个自己不喜欢的男孩.求有几种完美匹配(同上). 我觉得:求出上题答案,直接ans

Best Time to Buy and Sell Stock I &amp;&amp; II &amp;&amp; III

题目1:Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algori

[Lintcode] Best Time to Buy and Sell Stock I, II, III &amp;&amp; Maximum Subarray

买卖股票系列 && Subarray 相关题目: Best Time to Buy and Sell Stock I && II && III (IV 单独开贴) Maximum Subarray I && II 为什么这些我要总结到一起呢?因为思路基本一致. 题目简略: 买卖股票1: 一次买卖,利润最大. 买卖股票2: N次买卖,利润最大. 买卖股票3: 2次不重叠的买卖,利润最大. Maximum Subarray: Given an a

Leetcode 137. Single Number I/II/III

Given an array of integers, every element appears twice except for one. Find that single one. 本题利用XOR的特性, X^0 = X, X^X = 0, 并且XOR满足交换律. 1 class Solution(object): 2 def singleNumber(self, nums): 3 """ 4 :type nums: List[int] 5 :rtype: int 6

买卖股票的最佳时机I II III IV

I 假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. II 假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格.设计一个算法来找到最大的利润.你可以完成尽可能多的交易(多次买卖股票).然而,你不能同时参与多个交易(你必须在再次购买前出售股票). III 假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格.设计一个算法来找到最大的利润.你最多可以完成两笔交易. 样例 给出一个样例数组

【LeetCode】 Best Time to Buy and Sell Stock I II III IV 解题报告

Best Time to Buy and Sell Stock I 题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格. 如果只允许进行一次交易,也就是说只允许买一支股票并卖掉,求最大的收益. 分析:动态规划法.从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求. 代码:时间O(n),空间O(1). Best Time to Buy and Sell Stock II 题目:用一

[Leetcode][JAVA] Best Time to Buy and Sell Stock I, II, III

Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm

best-time-to-buy-and-sell-stock I &amp;&amp;II &amp;&amp; III &amp;&amp; IVbest-time-to-buy-and-sell-stock-ii

1.买卖股票的最佳时机 假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 1 public class Solution { 2 /** 3 * @param prices: Given an integer array 4 * @return: Maximum profit 5 */ 6 public int maxProfit(int[] prices) { 7 // write your code