打家劫舍II

题目描述(LeetCode)

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [2,3,2]
输出: 3
解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

示例 2:

输入: [1,2,3,1]
输出: 4
解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4

 

题目讲解

打家劫舍 II 和 打家劫舍 相比,题目只有一个变化。
这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。
这个规则会带来怎样的影响呢?
如果按照原来的解法,最要命的问题就是无法确定是否即抢了第一家又抢了最后一家。
那么,要怎么保证抢了第一家就不抢最后一家呢?

 

对于上面我们可以采取拆解的方式,变为两个打家劫舍I的方式,如下:

相比于第一题,此题目将首位也作为相邻,假设总共有N个房子,思路是:
1.分两次求解,首先是第一家到第N-1家,求得偷得最多的值,记Max01;
2.之后再次求得第2家到第N家可以偷的最大值,记为Max02;
3.最后比较Max01与Max02,将最大的那个值返回。

 

题目代码

对于上面的逻辑,用swift代码如下:

import UIKit

let numsay: [Int] = [2,7,9,3,1]
func robs(nums: [Int]) -> Int {
    if nums.count == 0 {
        return 0
    }
    if nums.count == 1 {
        return nums[0]
    }
    if nums.count == 2 {
        if nums[0] < nums[1] {
            return nums[1]
        } else {
            return nums[0]
        }
    }
    var dp1 = [Int]()
    var dp2: [Int] = [0]
    /**
     *偷第一家与不偷第一家
     */
    var fk_1: Int = 0
    var fk_2: Int = 0
    //偷第一家
    dp1.append(nums[0])
    if dp1[0] < nums[1] {
        dp1.append(nums[1])
    } else {
        dp1.append(dp1[0])
    }
    for i in 0..<nums.count - 1 {
        if i >= 2 {
            fk_1 = dp1[i - 1]
            fk_2 = dp1[i - 2] + nums[i]
            let temp = fk_1 > fk_2 ? fk_1 : fk_2
            dp1.append(temp)
        }
    }
    
    //不偷第一家,可以偷最后一家
    dp2.append(nums[1])
    if dp2[1] < nums[2] {
        dp2.append(nums[2])
    } else {
        dp2.append(dp2[1])
    }
    for i in 1..<nums.count {
        if i >= 3 {
            let fk_1 = dp2[i - 1]
            let fk_2 = dp2[i - 2] + nums[i]
            let temp = fk_1 > fk_2 ? fk_1 : fk_2
            dp2.append(temp)
        }
    }
    //比较大小
    let maxRobs = dp1[dp1.count - 1] > dp2[dp2.count - 1] ? dp1[dp1.count - 1] : dp2[dp2.count - 1]
    return maxRobs
}

let maxRobs = robs(nums: numsay)
print(maxRobs)

 

通过playground打印出结果如下:

 直接拷贝上面代码即可!

 

上面就是打家劫舍II的版本,希望对大家理解有所帮助,看完麻烦点个赞呗,谢谢!

posted @ 2019-08-21 22:45  国孩  阅读(159)  评论(0编辑  收藏  举报