博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode刷题198 打家劫舍 House Robber(简单) Python Java
阅读量:4127 次
发布时间:2019-05-25

本文共 2503 字,大约阅读时间需要 8 分钟。

题目:

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

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

示例 1:

输入: [1,2,3,1]

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

示例 2:

输入: [2,7,9,3,1]

输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

解题思路:

这题的考点是动态规划。 

动态规划一定要找递推公式!!!

1. 对这题来说,对每一家房子,在其前一家房子偷不偷的前提下,有两种可能的情况。 

2. 前一家房子被偷了,它就不能再偷了。前一家房子没被偷,它可以被偷也可以选择不偷。 
3. 可看出,每一个子问题都依赖于前一个子问题,同时每一个子问题都会产生至少一种情况(之多两种情况)状态转移方程:

dp[0] = num[0] (当i=0时)dp[1] = max(num[0], num[1]) (当i=1时)dp[i] = max(num[i] + dp[i - 2], dp[i - 1])   (当i !=0 and i != 1时)

dp[i]表示从0-i户可以打劫到的最大钱数。考虑在i处,我们只需要考虑两种情况,一种是偷了i-1,这时也就不能偷i。另一种是i-1没有偷,我们可以偷i,则有dp[i] = max(dp[i-1],dp[i-2]+nums[i]),第 i 个值为第(i-1)或者(i-2)加(i)的值,比较两者中的最大值。

class Solution(object):    def rob(self, nums):        """        :type nums: List[int]        :rtype: int        """        if not nums:           #输入0个数            return 0        elif len(nums) == 1:   #输入1给数时            return nums[0]        else:                  #输入2个数以上            dp = [0] * len(nums)  #定义一个数组,长度和原来的一样            dp[0] = nums[0]            dp[1] = max(nums[0], nums[1])            for i in range(2, len(nums)):                dp[i] = max(nums[i] + dp[i-2], dp[i-1])            return dp[-1]   #返回新数组的最后一个元素

 

以下是Java版本:

读题:  一个数组,不能取连续的两个值,求可得到和的最大值。

知识储备: 

动态规划 
动规解题的一般思路: 
1. 将原问题分解为子问题 
把原问题分解为若干个子问题,子问题和原问题形式相同或类似,只不过规模变小了。 子问题的解一旦求出要被保存。 
2.确定状态 
在用动态规划解题时,我们往往将和子问题相关的各个变量的一组取值,称之为一个 。一个状态对应于一个或多个子问题, 所谓某个状态下的,就是这个 所对应的子问题的解。 
3.确定一些初始状态(边界状态)的值 
4. 确定状态转移方程 
定义出什么是状态,以及在该状态下的后,就要找出不同的状态之间如何迁移――即如何从一个或多个已知的状态,求出另一个状态”(递推公式)

解题思路: 

1. 将原问题分解为子问题——今天偷不偷

2. 确定状态——每间房子可以有两个状态:偷或者不偷

3. 确定一些边界状态——当走到最后一间房子的时候结束

4. 确定状态转移方程——判断偷和不偷这件房子,那个收益大,将收益大的选作最佳方案

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

另一种解法:

1.	public class Solution {  2.	    public int rob(int[] nums) {  3.	        if (nums.length == 0) {  4.	            return 0;  5.	        }  6.	        if (nums.length == 1) {  7.	            return nums[0];  8.	        }  9.	        int now  = 0;  10.	        int last = 0;  11.	          12.	        for (int i=0; i

 

转载地址:http://vpuvi.baihongyu.com/

你可能感兴趣的文章
前阿里手淘前端负责人@winter:前端人如何保持竞争力?
查看>>
【JavaScript 教程】面向对象编程——实例对象与 new 命令
查看>>
我在网易做了6年前端,想给求职者4条建议
查看>>
SQL1015N The database is in an inconsistent state. SQLSTATE=55025
查看>>
RQP-DEF-0177
查看>>
Linux查看mac地址
查看>>
Linux修改ip
查看>>
MySQL字段类型的选择与MySQL的查询效率
查看>>
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
IPS开发手记【一】
查看>>
Java通用字符处理类
查看>>
文件上传时生成“日期+随机数”式文件名前缀的Java代码
查看>>
Java代码检查工具Checkstyle常见输出结果
查看>>
北京十大情人分手圣地
查看>>
Android自动关机代码
查看>>
Android中启动其他Activity并返回结果
查看>>
2009年33所高校被暂停或被限制招生
查看>>
GlassFish 部署及应用入门
查看>>
iWatch报错: Authorization request cancled
查看>>