打家劫舍II

Posted guohai-stronger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打家劫舍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 numsArray: [Int] = [1,2,3,1]
func robs(numsArr: [Int]) -> Int 
    if numsArr.count == 0 
        return 0
    
    if numsArr.count == 1 
        return numsArr[0]
    
    if numsArr.count == 2 
        if numsArr[0] < numsArr[1] 
            return numsArr[1]
         else 
            return numsArr[0]
        
    
    var dp1 = [Int]()
    var dp2 = [Int]()
    /**
     *偷第一家与不偷第一家
     */
    
    //偷第一家
    for i in 0..<numsArr.count - 1 
        if i < 2 
            dp1.append(numsArr[0])
            if dp1[0] < numsArr[1] 
                dp1.append(numsArr[1])
             else 
                dp1.append(dp1[0])
            
         else 
            let fk_1 = dp1[i - 1]
            let fk_2 = dp1[i - 2] + numsArr[i - 1]
            let temp = fk_1 > fk_2 ? fk_1 : fk_2
            dp1.append(temp)
        
    
    
    //不偷第一家,可以偷最后一家
    for i in 1..<numsArr.count 
        if i < 3 
            dp2.append(numsArr[1])
            if dp2[0] < numsArr[2] 
                dp2.append(numsArr[2])
             else 
                dp2.append(dp2[0])
            
         else 
            let fk_1 = dp2[i - 1]
            let fk_2 = dp2[i - 2] + numsArr[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(numsArr: numsArray)
print(maxRobs)

通过playground打印出结果如下:

技术图片

 直接拷贝上面代码即可!

 

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

以上是关于打家劫舍II的主要内容,如果未能解决你的问题,请参考以下文章

213.打家劫舍II

java刷题--213打家劫舍II

LeetCode-213. 打家劫舍 II

213-打家劫舍 II

算法:打家劫舍213. House Robber II

1线性DP 213. 打家劫舍 II