打劫房屋i:
題目內容:
假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。
樣例:給定[3, 8, 4]
, 返回8
.
挑戰:o(n) 時間複雜度 且 o(1) 儲存。
演算法分析:
前提:對於某一間房子i,如果盜賊要打劫該房子,則房間對序號為i-1的房子(即前一所房子)盜賊不能進行打劫才能保證系統不報警。因此,很容易得出動態規劃的表示式:
①建立乙個陣列dp,dp[i]用來表示盜賊打劫到第i所房子時所能獲得的最大金額數;
②根據前提的描述,盜賊不打劫當前房子,則dp[i] = dp[i-1];否則dp[i] = dp[i-2] + a[i];
因此dp[i] = max;
**:
publicclass
solution
long dp = new long[a.length+1];
dp[1] = a[0];
for(int i=1;i*/
//空間開銷為o(1);
public
long houserobber(int
a) if(a.length==1)
long dp_i_1 = a[1];
long dp_i_2 = a[0];
for(int i=2;i)
return
dp_i_1;
}}
打劫房屋ii:
題目內容:
在上次打劫完一條街道之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子圍成了乙個圈,這就意味著第一間房子和最後一間房子是挨著的。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。
注意事項:
這題是house robber的擴充套件,只不過是由直線變成了圈。
樣例:給出nums =[3,6,4]
, 返回6
, 你不能打劫3
和4
所在的房間,因為它們圍成乙個圈,是相鄰的。
演算法分析:
本題在打劫房屋i的基礎上增加了乙個條件就是第一所房子與最後一所房子也不能兼得,其實本質並沒有發生變化。在i中我們的建立的動態規劃陣列為dp[i]表示盜賊打劫到第i所房子獲利的最大值,因此我們同樣可以建立兩個陣列dp_1 和 dp_2 分別用來記錄打劫區間為[1, n-1] 與 [2,n]的獲利情況。這是因為第一所房子與最後一所房子不能夠相鄰,因此將其分為兩個區間[1,n-1]與[2,n]後則就將問題化為了直線的打劫問題,也就可以運用i中的方法求解。
**:
publicclass
solution
if(nums.length==1)
int dp_1 = new
int[nums.length-1];
int dp_2 = new
int[nums.length-1];
//不打劫最後一所房子則從第一所房子開始打劫
for(int i=0;i)
if(i==1)
if(i>1)
}//打劫最後一所房子則從第二所房子開始打劫
for(int i=1;i)
if(i==2)
if(i>2)
}return dp_1[nums.length-2]>dp_2[nums.length-2]?dp_1[nums.length-2]:dp_2[nums.length-2];
}}
打劫房屋iii:
題目描述:
在上次打劫完一條街道之後和一圈房屋之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子組成的區域比較奇怪,聰明的竊賊考察地形之後,發現這次的地形是一顆二叉樹。與前兩次偷竊相似的是每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且當相鄰的兩個房子同一天被打劫時,該系統會自動報警。算一算,如果今晚去打劫,你最多可以得到多少錢,當然在不觸動報警裝置的情況下。
樣例:
3
/ \2 3
\ \
3 1
竊賊最多能偷竊的金錢數是 3 + 3 + 1 = 7.
3
/ \4 5
/ \ \
1 3 1
竊賊最多能偷竊的金錢數是 4 + 5 = 9.
演算法分析:
打劫房屋i、ii均為對陣列的動態規劃處理,但本題是要求對二叉樹進行乙個動態規劃處理。對於本題,首先要了解怎樣是相鄰:有直接連線的節點之間算相鄰節點,即父節點與親子節點;
對於二叉樹中的某乙個節點i,它也有偷與不偷這兩個選項,若偷,則兩個子節點不能偷;否則,兩個子節點可以偷。與i、ii不同的是,i、ii中對當前的房屋i,偷與不偷僅需把其中的較大者保留下來進行,因為後續的結果均是建立在前者為最優解的基礎上進行的,而且dp[i] = max一定能保證不發生衝突;但是對於二叉樹,當前節點i並不能那麼方便的找到其子節點的子節點的最優解,因此並不能同i、ii那樣僅記錄最優解。對於二叉樹的節點而言,其最容易訪問到的就是它的兩個子節點。因此,可以建立乙個大小為2的一維陣列dp,其中dp[0]用來記錄偷當前節點所能獲利值,dp[1]用來記錄不偷當前的值所能獲利的值。因為二叉樹由根節點開始進行發散,因此可以用後序遍歷的方式最終返回乙個二維陣列。動態規劃表示式如下:
對於某乙個節點node,若偷:dp[0] = left[1] + right[1] + node.val; 若不偷:dp[1] = max + max;
**:
/*** definition of treenode:
* public class treenode
* } */
public
class
solution ;
return
result;
}int result = new
int[2];
int left =posttrack(node.left);
int right =posttrack(node.right);
//偷當前結點
result[0] = left[1] + right[1] +node.val;
//不偷當前節點
result[1] = math.max(left[0],left[1]) + math.max(right[0],right[1]);
return
result;
}public
inthouserobber3(treenode root)
}
lintcode 打劫房屋
假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢,算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的...
LintCode 打劫房屋
描述 假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢,算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警...
lintcode打劫房屋
原題位址 題目 假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢,算一算,如果今晚去打劫,你最多可以得到多少錢 在...