題目
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.
解析
題目中有兩點(diǎn)需要注意,一是不是偷連續(xù)兩天的屋子,二是保證所偷屋子的總和最大。
這里邏輯到的算法是動(dòng)態(tài)規(guī)劃算法,即數(shù)組中不連續(xù)的值的最大值。
假設(shè)maxVal[i]為到達(dá)第i個(gè)房間的最大value,那么就有:
maxVal[i] = max(maxVal[i - 2] + nums[i], maxVal[i - 1])
該公式可以理解為:
到第i個(gè)房間的最大收益為,到第i-2個(gè)房間的最大收益與第i個(gè)房間的收益之和,與到第i-1個(gè)房間最大收益,這兩者的最大值。
此題和上樓問(wèn)題類似(LeetCode 70),即最后一步是由其上一步上一階和上上步上兩階上來(lái)之和。
得出了該公式之后,代碼的實(shí)現(xiàn)就簡(jiǎn)單了。
代碼(C語(yǔ)言)
int max(int val1, int val2);
int rob(int* nums, int numsSize) {
if (nums == NULL || numsSize == 0)
return 0;
if (numsSize == 1) {
return nums[0];
}
int* maxValueArr = (int*)malloc(sizeof(int) * numsSize);
maxValueArr[0] = nums[0];
maxValueArr[1] = max(nums[0], nums[1]);
for (int i = 2; i < numsSize; ++i) {
maxValueArr[i] = max(maxValueArr[i - 2] + nums[i], maxValueArr[i - 1]);
}
int maxValue = maxValueArr[numsSize - 1];
free(maxValueArr);
return maxValue;
}
int max(int val1, int val2) {
return val1 > val2 ? val1 : val2;
}