1. 程式人生 > >[leetcode] House Robber

[leetcode] House Robber

最大收益 ont 運行時 ons pub ret || view 找到

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 1:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
             Total amount you can rob = 2 + 9 + 1 = 12.
分析:這個題目翻譯如下:一個數組nums,求這個數組不相鄰的元素和最大是多少。很容易理解這個題和動態規劃有關,因為某個位置取不取和前面的狀態有關。這種類似找極值的問題都考慮用動態規劃求解。首先維護一個數組dp,dp[i]表示到第i個位置可以獲得最大的數字和是多少。下面的關鍵就是如何找到狀態轉移方程了。針對這個題目,我們以[2,7,9,3,1]為例: 0位置最大收益:肯定是dp[0]=2; 1位置最大收益:有兩種可能,一種是0位置取了,1位置就不取;第二種是0位置不取,1位置取;也就是:dp[1] = max{dp[0],dp[1]}=9; 2位置最大收益:也有兩種可能,一種是0位置最大收益加上2位置的值,一種是取1位置最大收益,不取2位置最大收益,即:dp[2] = max{dp[1],dp[0]+nums[2]}=11; 3位置最大收益:原理同上,即:dp[3]=max{dp[2],dp[1]+nums[3]}=11; 4位置最大收益:原理同上,即:dp[4]=max{dp[3],dp[2]+nums[4]}=12; 所以輸出dp[4]和dp[3]的最大值:12。 由上面的分析,我們就找到了從2位置開始的狀態轉移方程:dp[i]=max{dp[i-1],dp[i-2]+nums[i] (i>=2)。 代碼如下:
 1
public int rob(int[] nums) { 2 if ( nums == null || nums.length == 0 ) return 0; 3 if ( nums.length == 1 ) return nums[0]; 4 int[] dp = new int[nums.length]; 5 dp[0] = nums[0]; 6 dp[1] = Math.max(nums[0],nums[1]); 7 for ( int i = 2 ; i < nums.length ; i ++ ){ 8 dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]); 9 } 10 return Math.max(dp[nums.length-1],dp[nums.length-2]); 11 }

運行時間3ms,看了一下1ms、0ms的答案,都是舍棄dp數組,直接用一個變量表示。我覺得這反而不能體現出動態規劃的思想,所以就不整理了。理解動態規劃的思想才是最重要的。

[leetcode] House Robber