ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

打家劫舍II

2019-08-21 22:56:49  阅读:240  来源: 互联网

标签:count 偷窃 dp2 dp1 numsArr 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的版本,希望对大家理解有所帮助,看完麻烦点个赞呗,谢谢!

标签:count,偷窃,dp2,dp1,numsArr,II,房屋,打家劫舍
来源: https://www.cnblogs.com/guohai-stronger/p/11386285.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有