lintcode打劫房屋

原題地址
題目:
假設你是一個專業的竊賊,準備沿着一條街打劫房屋。每個房子都存放着特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝着相互聯繫的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。

給定一個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。

您在真實的面試中是否遇到過這個題? Yes
樣例
給定 [3, 8, 4], 返回 8.

分析:
簡單dp題。當前房屋 i 的最大可達錢取決於dp[i - 2]和dp[i - 3]的最大值(dp[i - 4]的情況屬於dp[i - 2])。
注意返回值要爲long型。
時間複雜度o(n),空間o(n)

public long houseRobber(int[] A) {
        long[] dp = new long[A.length];
        if (A.length < 1) {
            return 0;
        }
        if (A.length == 1) return A[0];
        dp[0] = A[0];
        dp[1] = A[1];
        long max = Math.max(dp[0], dp[1]);
        if (A.length <= 2) {
            return max;
        }
        dp[2] = dp[0] + A[2];
        if (dp[2] > max) max = dp[2];
        for (int i = 3; i < A.length; i++) {
            dp[i] = (dp[i - 2] > dp[i - 3] ? dp[i - 2] : dp[i - 3]) + A[i];
            if (dp[i] > max) {
                max = dp[i];
            }
        }
        return max;
    }

改進的時間複雜度o(n),空間o(1),用dp1和dp2保存dp[i - 3]和dp[i - 2]。

public long houseRobber(int[] A) {
        if (A.length < 1) {
            return 0;
        }
        if (A.length < 2) {
            return A[0];
        }
        long dp1 = A[0];
        long dp2 = A[1];
        long max = Math.max(dp1, dp2);
        if (A.length == 2) {
            return max;
        }
        max = (dp1 + A[2]) > dp2 ? (dp1 + A[2]) : dp2;
        long temp = max;
        long tempLast = temp;
        for (int i = 3; i < A.length; i++) {
            temp = (dp1 > dp2 ? dp1 : dp2) + A[i];
            if(temp > max) max = temp;
            dp1 = dp2;
            dp2 = tempLast;
            tempLast = temp;
        }
        return max;
    }

另外一種思路
參考網址
用一個二維數組dp[A.length][2],其中對於第i所房子,dp[i][0]表示不打劫i,此時其能獲得的最大錢數爲:
dp[i][0] = max(dp[i - 1][0] ,dp[i - 1][1])
dp[i][1]表示打劫i,其等於不打劫上一家的情況下,再加上i的錢數:
dp[i][1] = dp[i - 1][0] + A[i];

 public long houseRobber(int[] A) {  
        if(A.length==0)  
            return 0;  
        long[][] dp = new long[A.length][2];  
        dp[0][1] = A[0];
        for(int i=1;i<A.length;++i){  
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]);  
            dp[i][1] = dp[i-1][0]+A[i];  
        }  
        return Math.max(dp[A.length-1][0],dp[A.length-1][1]); 
    }
發佈了24 篇原創文章 · 獲贊 14 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章