213 House Robber

# 213 House Robber

题目来源:

https://leetcode.com/problems/house-robber-ii/description/

题意分析:

给定一个正整数列表,列表头尾相连成环,要求不能取相邻的正整数,输出能取出的数的和。

题目思路:

首先假设该列表不成环,那么就是经典的动态规划问题,设前i+1个正整数取到的最大和为sum[i],容易知道sum[0]=nums[0],sum[1]=max(nums[0],nums[1])。从i=2开始,sum[i]可以从两个方向获得,一是从sum[i-1]来,这时nums[i]不可取,二是从sum[i-2]来,这时nums[i]可取。两种方式都可能使sum[i]取得最大值,那么可以得到动态转移方程sum[i]=max(sum[i-1],(sum[i-2]+nums[i]))

接下来取消假设,即该列表成环,那么跟不成环有什么不同呢?原来没成环时,首尾是可以一起选的,因为成环,首尾不能一起选了。那我们可以分两种情况,一是头可以选,尾不可以选,二是头不可以选,尾可以选。可以选并不是一定要选的意思。这样的话,一个环就可以分成两条不成环的列表了,一是nums[0:-1],一是nums[1:]。算出两个列表最后的sum取最大值就成。

测试之后发现漏了两种特殊情况:

第一种,举个栗子:[1,3,1,3,100]。显然答案是100+3=103但是根据思路,分成两列表[1,3,1,3][3,1,3,100],无法得到正确结果。原因是对于[3,1,3,100], 1 处默认的sum1,但其实可以通过第一个3更新为3,但它又不能调用动态转移方程(因为不存在1的前两位),处理办法是

sum[3]=max(sum[2],(sum[1]+nums[3])(sum[0]+nums[3]))

这样就可以把后面的sum值都更新了。

第二种,列表长度为3的情况,分成了两个长度为2的列表,算法施展不开手脚。。

 

代码:

1. class Solution:  

2.     def rob(self, nums):  

3.         """ 

4.         :type nums: List[int] 

5.         :rtype: int 

6.         """  

7.         if (nums==[]):  

8.             return 0  

9.         if (len(nums)==1):  

10.             return nums[0]  

11.         if (len(nums)==2):  

12.             return max(nums[0],nums[1])  

13.         if (len(nums)==3):  

14.             return max(nums[0],nums[1],nums[2])  

15.           

16.         temp_res=[0]*(len(nums)-1)  

17.         temp_res[0]=nums[0]  

18.         temp_res[1]=nums[1]  

19.           

20.         for i in range(2,len(nums)-1):  

21.             temp_res[i]=max(temp_res[i-1],temp_res[i-2]+nums[i])  

22.             if (i==3):  

23.                 temp_res[i]=max(temp_res[i],temp_res[i-3]+nums[i])  

24.           

25.         res=temp_res[len(nums)-2]  

26.           

27.         nums=nums[1:]  

28.         temp_res=[0]*len(nums)  

29.         temp_res[0]=nums[0]  

30.         temp_res[1]=nums[1]  

31.         for i in range(2,len(nums)):  

32.             temp_res[i]=max(temp_res[i-1],temp_res[i-2]+nums[i])  

33.             if (i==3):  

34.                 temp_res[i]=max(temp_res[i],temp_res[i-3]+nums[i])  

35.           

36.         res=max(res,temp_res[len(nums)-1])  

37.           

38.         return res  

39.           

40.           

41.           

 

提交细节:

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值