题目
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.
解题思路
动态规划题目
核心在于找到推导公式,可以假设robMax[i]是前i个屋子抢劫所得最大值,第i个房间是否抢劫有两种情况:
- 抢劫第i个房间, rob[i]表示第i次抢劫的话前i个屋子抢劫所得最大值
- 不抢劫第i个房间,notRob[i]表示第i次不抢劫的话前i个屋子抢劫所得最大值
所以有如下公式
robMax[i] = max{ rob[i], notRob[i]} —-(1)
抢劫第i个房间,则第i-1个房间不能抢劫,有
rob[i] = notRob[i-1] + nums[i] —- (2)
不抢劫前i个房间的抢劫最大值,相当于抢劫前i-1个房间的最大值,有
notRob[i] = rob[i-1] —- (3)
所以公式(1)可以推导为
robMax[i] = max{rob[i-2] + nums[i], rob[i-1]} i>2 —-(4)
申请数组rob需要占用O(n)的空间复杂度,考虑到公式推导只需要知道前面两个数rob[i-1], rob[i-2],可以只申请两个变量用于记录前面两个值,则空间复杂度将为O(1)
代码
func rob(nums []int) int {
len1 := len(nums)
if 0 == len1 {
return 0
}else if 1 == len1 {
return nums[0]
}
var rob []int
var max int
rob = make([]int, len1)
rob[0] = nums[0]
if nums[0] > nums[1] {
rob[1] = nums[0]
max = nums[0]
} else {
rob[1] = nums[1]
max = nums[1]
}
for i := 2; i < len1; i++ {
if rob[i-1] > rob[i-2] + nums[i] {
rob[i] = rob[i-1]
} else {
rob[i] = rob[i-2] + nums[i]
}
if max < rob[i] {
max = rob[i]
}
}
return max
}