1. 程式人生 > >關於LeetCode中House Robber一題的理解

關於LeetCode中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.

    題目的意思就是一個竊賊要盜竊一條街上的房子。每個房子裡有固定數量的錢,竊賊如果在一個晚上偷了兩個相鄰的房子就會觸發警報,警察就會來抓這個竊賊。那麼,怎樣一個盜竊方案能使竊賊拿到的錢最多且不觸發警報。
public int rob(int[] num) {
    int[][] dp = new int[num.length + 1][2];
    for (int i = 1; i <= num.length; i++) {
        dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
        dp[i][1] = num[i - 1] + dp[i - 1][0];
    }
    return Math.max(dp[num.length][0], dp[num.length][1]);
}
   稍微解釋一下這個程式碼,dp這個二維陣列代表盜竊前i棟房子帶來的最大收益,其中第二維一共有兩個選擇分別是0和1。0代表不盜竊第i棟房子,1代表盜竊第i棟房子。換句話就是說,dp[i][0]代表盜竊前i棟房子的最大收益,但是不包括第i棟房子的(因為沒有盜竊第i棟房子),而dp[i][0]代表盜竊前i棟房子的最大收益,其中包括了第i棟房子的(因為第i棟房子被盜竊了)。

   其實對一棟房子來說,結果無非是兩種,被盜竊和沒被竊。所以說,才會有之前分0和1兩種情況進行討論。如果第i棟房子沒被盜竊的話,那麼dp[i][0] = dp[i-1][0]和dp[i-1][1]中的最大值。這個比較好理解,如果第i棟房子沒被竊,那麼最大總收益dp[i][0]一定和dp[i-1][0],dp[i-1][1]這兩個之中最大的相同。而假若第i棟房子被竊,那麼dp[i][1]一定等於第num[i-1](注意,這裡的i是從1開始的,所以i-1正好對應num中的第i項,因為num中的index是從0開始的)+dp[i-1][0],因為第i棟房子已經被竊了,第i-1棟房子肯定不能被竊,否則會觸發警報,所以我們只能取dp[i-1][0]即第i-1棟房子沒被竊情況的最大值。迴圈結束,最後返回dp[num.length][0]和dp[nums.length][1]較大的一項。

    這道問題屬於動態規劃問題,你開啟問題的tags會發現“Dynamic programming”即動態規劃的字樣,動態規劃我也不是很懂建議大家直接去看演算法導論吧。