DEnjoy

导航

leetcode日记 HouseRobber I II

House Robber I

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.

 

大意:你是一个专业盗贼,将要抢劫一条街上的房子,每个房子都有一定的钱可以抢,唯一能阻止你抢劫的是警报器,如果相邻的两个房子被抢,那么警报器就会触发。

现在给你一个非负的数组代表每个房子的金额,求出如何能够抢劫到最大数额的钱而不触发警报。

分析:不知道为什么,看到这个题很明显的就可以向动态规划上靠,感觉很像上楼梯和斐波那契数列那种,因此就向这个方向想想,假设数组有五个元素,那么对于能够抢到的最多的钱,一定是  第五个元素的金额加上前三个元素组成的数列所求的结果 与 前四个元素所组成元素所求结果  这两个结果中比较大的那个,那么这样子5个元素数列问题就转化成 4个元素数列问题和3个元素数列问题。以此类推,只要知道一个元素数列问题的结果和两个元素数列问题的结构就可以依次推出之后的结果。复杂度:时间上,线形时间内完成,只需要遍历一次。空间上,线形空间内完成,只需要额外的一个和原数组大小相同的数组。

class Solution(object):
    def rob(self, nums):
        lens=len(nums)
        if lens==0:
            return 0
        if lens==1:
            return nums[0]
        if lens==2:
            return max(nums)
        result=[]
        result.append(nums[0])
        result.append(max(nums[:2]))
        for i in xrange(2,lens):
            tem=max(result[i-1],result[i-2]+nums[i])
            result.append(tem)
        return result[-1]

 

House Robber II 

 

Note: This is an extension of House Robber.

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

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.

大意:这是上一题的扩展

这一次街道变成环状街道,警报触发模式一样,这一次怎样抢劫到最多的钱。

分析:最直接的思路为将这个环形街道变成线形街道,这样就可以使用上一题的模式进行解答。根据此思路进行分析,同样假设5个元素,同样如果要抢到最多的钱,那么一定是 第五个元素加上二三元素(第一第四元素相邻第五元素,因此除去)组成的数列问题的结果 与 前四元素组成的数列问题的结果 这两结果中比较大的即为答案。那么这样就将原本的环形问题转化为两个线形问题。这样即可得到答案。复杂度:将一个环形问题拆成两个线形问题,因此时间上复杂度为O(2n),依然是线性时间,空间上重用同一条数组的话依然只需要O(n)的空间。

 

class Solution(object):
    def rob1(self,nums):#House Robber I的解法
        lens=len(nums)
        if lens==0:
            return 0
        if lens==1:
            return nums[0]
        if lens==2:
            return max(nums)
        result=[]
        result.append(nums[0])
        result.append(max(nums[:2]))
        for i in xrange(2,lens):
            tem=max(result[i-1],result[i-2]+nums[i])
            result.append(tem)
        return result[-1]

    def rob(self,nums):
        lens=len(nums)
        if lens==1 or lens ==3 or len==2:
            return max(nums)
        if lens==0:
            return 0
        line1=nums[:lens-1]
        line2=line1[1:lens-2]
        tem1=self.rob1(line1)
        tem2=self.rob1(line2)
        return max(tem1,nums[-1]+tem2)

 

posted on 2017-01-11 18:38  DEnjoy  阅读(154)  评论(0编辑  收藏  举报