zoukankan      html  css  js  c++  java
  • 打家劫舍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的版本,希望对大家理解有所帮助,看完麻烦点个赞呗,谢谢!

  • 相关阅读:
    获取指定扩展名的文件 分类: python 小练习 20130514 16:06 229人阅读 评论(0) 收藏
    #遍历E盘下的mp3文件 分类: python 小练习 python 20130514 18:27 303人阅读 评论(0) 收藏
    🍖Linux输出重定向
    🍖手动添加用户
    🍗文件权限管理
    🍖文件管理之打包压缩
    🍖文件处理三剑客:sed awk grep
    🍖权限管理之用户与用户组
    🍖文件管理之字符处理 sort uniq cut tr wc
    🍖文件处理之上传下载
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/11386285.html
Copyright © 2011-2022 走看看