题目描述(LeetCode)

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

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

示例 1:

输入: [,,,]
输出:
解释: 偷窃 号房屋 (金额 = ) ,然后偷窃 号房屋 (金额 = )。
  偷窃到的最高金额 = + = 。

示例 2:

输入: [,,,,]
输出:
解释: 偷窃 号房屋 (金额 = ), 偷窃 号房屋 (金额 = ),接着偷窃 号房屋 (金额 = )。
  偷窃到的最高金额 = + + = 。

题目讲解

很多人拿到上面的意思,可能还是没有理解透彻,讲解一下思路:

  • 标签: 动态规划
  • 动态规划方程: dp[n] = MAX( dp[n-1], dp[n-2] + num )
  • 由于不可以在相邻的房屋闯入,所以在当前位置n房屋可盗窃的最大值,要么就是 n-1 房屋可盗窃的最大值,要么就是 n-2 房屋可盗窃的最大值加上当前房屋的值,二者之间取最大值
  • 举例说明: 1号房间可盗窃的最大值为3,即为dp[1] = 3, 2号房间可盗窃最大值为4,即为dp[2] = 4, 3号公寓自身为2,即为num=2,那么 dp[3] = MAX( dp[2], dp[1] + num ) = MAX(4, 3+2) = 5,3 号房间可盗窃最大值为 5
  • 时间复杂度为: O(n), n为数组长度

下面我们通过图解,通过例子[3,1,2,4]来讲解:

2.1

上面代表是举出例子,3,1,2,4,下面的代表是dp函数,也就是前面相加之和记为dp

开始dp[0] = 0,dp[1] = num[0]= 3

1/5

2.2

dp[0] = 0, dp[1] = 3, dp[i] = MAX(dp[i - 1], dp[i - 2] + num[i - 1] )---->dp[0],是从0开始

dp[2] = MAX(dp[1], dp[0] + num[i]) = MAX(3, 0 + 1) = 3

所以dp[2] = 3

2.3

dp[0] = 0, dp[1] = 3, dp[i] = MAX(dp[i - 1], dp[i - 2] + num[i - 1] )---->dp[0],是从0开始

dp[3] = MAX(dp[2], dp[1] + num[2]) = MAX(3, 3 + 2) = 5

所以dp[3] = 5

2.4

dp[0] = 0, dp[1] = 3, dp[i] = MAX(dp[i - 1], dp[i - 2] + num[i - 1] )---->dp[0],是从0开始

dp[4] = MAX(dp[3], dp[2] + num[3]) = MAX(5, 3 + 4) = 7

所以dp[4] = 7

题目代码

(1)针对上面的思路分析,下面是java 代码

class Solution {
public int rob(int[] nums) {
int len = nums.length;
if(len == )
return ;
int[] dp = new int[len + ];
dp[] = ;
dp[] = nums[];
for(int i = ; i <= len; i++) {
dp[i] = Math.max(dp[i-], dp[i-] + nums[i-]);
}
return dp[len];
}
}

(2)swift代码如下(可在playground直接运行)

let numsArr: [Int] = [,,,]
var newNumArr = [Int]()
func robs(numArr: [Int]) -> Int {
if numArr.count == {
return
}
  //newNumArr[0] = 0这种写法是错误的,swift数组不允许直接赋值,会造成两个数组同时操作同一块地址空间
newNumArr.append(0)
newNumArr.append(numArr[0])
var fk_1 =
var fk_2 =
for i in ..<(numArr.count + ) {
fk_1 = newNumArr[i - ]
fk_2 = newNumArr[i - ] + numArr[i - ]
let temp = fk_1 > fk_2 ? fk_1 : fk_2
newNumArr.append(temp)
}
return newNumArr[numArr.count] }
let maxRob = robs(numArr: numsArr)
print(maxRob)

输出结果是7,和上面一样!

上面是打家劫舍的第一版本,后续我们将继续出版其他版本的打家劫舍,欢迎大家关注,谢谢

打家劫舍I的更多相关文章

  1. (leetcode:选择不相邻元素,求和最大问题):打家劫舍(DP:198/213/337)

    题型:从数组中选择不相邻元素,求和最大 (1)对于数组中的每个元素,都存在两种可能性:(1)选择(2)不选择,所以对于这类问题,暴力方法(递归思路)的时间复杂度为:O(2^n): (2)递归思路中往往 ...

  2. leetcode 198 打家劫舍 Python 动态规划

    打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定 ...

  3. 213 House Robber II 打家劫舍 II

    注意事项: 这是 打家劫舍 的延伸.在上次盗窃完一条街道之后,窃贼又转到了一个新的地方,这样他就不会引起太多注意.这一次,这个地方的所有房屋都围成一圈.这意味着第一个房子是最后一个是紧挨着的.同时,这 ...

  4. Leetcode337. 打家劫舍 III

    Leetcode 337. 打家劫舍 III 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为"根". 除了"根& ...

  5. 【LeetCode】198. 打家劫舍

    打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定 ...

  6. 打家劫舍II

    题目描述(LeetCode) 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的 ...

  7. [LeetCode] 198. 打家劫舍II ☆☆☆(动态规划)

    描述 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的 ...

  8. [LeetCode] 198. 打家劫舍 ☆(动态规划)

    描述 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定一个 ...

  9. [LeetCode] 213. House Robber II 打家劫舍 II

    Note: This is an extension of House Robber. After robbing those houses on that street, the thief has ...

随机推荐

  1. 自定义的操作Cookie的工具类

    可以在SpringMVC等环境中使用的操作Cookie的工具类 package utils; import java.io.UnsupportedEncodingException; import j ...

  2. Java解决java.io.FileNotFoundException: E:\work\work (拒绝访问。)

    一.问题 在使用FileInputStream或FileOutputStream时会遇到如下问题1和问题2. 问题1: java.io.FileNotFoundException: .\xxx\xxx ...

  3. FileInputFormat 的实现之TextInputFormat

    说明 TextInputFormat默认是按行切分记录record,本篇在于理解,对于同一条记录record,如果被切分在不同的split时是怎么处理的.首先getSplits是在逻辑上划分,并没有物 ...

  4. 论文阅读 | Recurrent Attentional Reinforcement Learning for Multi-label Image Recognition

    源地址 arXiv:1712.07465: Recurrent Attentional Reinforcement Learning for Multi-label Image Recognition ...

  5. UDP丢包原因总结

    丢包检查方法 给每个UDP包编号,对比收发端的接收到的包.对于UDP协议层上的包,例如RTP包,可以从RTP包中读出包的序列号进行判断. 抓包.发送端和接收端分别抓包.linux下可以使用tcpdum ...

  6. MyBatis(六):Mybatis Java API编程实现一对多、一对一

    最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...

  7. [.NET逆向] [入门级]de4dot参数详解

    为了避免被0xd4d(de4dot作者)认为是"N00bUser"为了认识到Some of the advanced options may be incompatible, ca ...

  8. JVM探究之 —— 垃圾回收(一)

    垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物.事实上,GC的历史比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和 ...

  9. MongoTemplate进行增删改查

    转载自:https://blog.csdn.net/sinat_35821285/article/details/83511203#commentBox 1.首先pom.xml <!-- spr ...

  10. asp.netcore Log4Net连接kafka的方法

    1.NuGet添加2个包: Microsoft.Extensions.Logging.Log4Net.AspNetCore log4net.Kafka.Core 2.Program里修改CreateW ...