扣初级算法-32-动态规划-打家劫舍

本文介绍了如何使用动态规划解决打家劫舍问题,即在不触发防盗系统的情况下,小偷如何最大化盗窃金额。通过分析问题,定义状态转移方程,给出两种不同的动态规划实现方式,包括原始的二维数组实现和优化后的单维数组实现,旨在帮助读者理解动态规划在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

学习目标:

本次学习目标为 力扣初级算法-动态规划,其中主要的LC如下:

  • 打家劫舍

学习内容:

  1. 打家劫舍 -----([链接](https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xnq4km/)
    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
    给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 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 。

解题思路:

  • 解法一: 通用
  • 解题思路:
  • 代码实现:
    • 动态规划
    • 分析: 数组中存放的是金额,小偷可以选择是偷还是不偷
    • 定义一个二维数组 dp[length][2]
    • 其中 dp[i][0]表示第 i+1 家中偷了的最大金额
    • dp[i][0] 表示第 i+1 家没偷的最大总金额
    • 1.假设第 i 家没有偷,那么第 i+1 家,可以是偷的,也可以是没偷的。
    • dp[i][0]=max(dp[i-1][0],dp[i-1][1]) 表示的是第 i+1 家没偷,那么第 i 家没有偷都是可以的,所以我们取两者的最大值即可。
    • 2.假设第 i+1 家偷了,那么第 i 家 必须是没有偷的
    • dp[i][1]=dp[i-1][0]+nums[i] ,这里nums[i]表示的是第i+1家偷的金额
    • 递推公式找出来之后我们再来看下边界条件,第一家可以选择偷,也可以选择不偷
    • dp[0][0]=0,第一家没偷
    • dp[0][1]=nums[0],第一家偷了
	
	/**
	 * 动态规划
	 * 分析: 数组中存放的是金额,小偷可以选择是偷还是不偷
	 * 定义一个二维数组 dp[length][2]
	 * 其中 dp[i][0]表示第 i+1 家中偷了的最大金额
	 * dp[i][0] 表示第 i+1 家没偷的最大总金额
	 * 1.假设第 i 家没有偷,那么第 i+1 家,可以是偷的,也可以是没偷的。
	 * dp[i][0]=max(dp[i-1][0],dp[i-1][1]) 表示的是第 i+1 家没偷,那么第 i 家没有偷都是可以的,所以我们取两者的最大值即可。
	 * 2.假设第 i+1 家偷了,那么第 i 家 必须是没有偷的
	 * dp[i][1]=dp[i-1][0]+nums[i] ,这里nums[i]表示的是第i+1家偷的金额
	 * 递推公式找出来之后我们再来看下边界条件,第一家可以选择偷,也可以选择不偷
	 * dp[0][0]=0,第一家没偷
	 * dp[0][1]=nums[0],第一家偷了
	 *
	 */
	public int Rob01(int[] nums) {

		// 边界条件处理
		if (null == nums || nums.length == 0){
			return 0;
		}

		int length = nums.length;
		int[][] dp = new int[length][2];

		// 第一家 没偷
		dp[0][0] = 0;
		// 第一节偷了
		dp[0][1] = nums[0];

		for (int i = 1; i < length; i++) {
			dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]);
			dp[i][1] = dp[i-1][0] + nums[i];
		}
		return Math.max(dp[length-1][0],dp[length-1][1]);


	}


	/**
	 * 动态规划优化
	 *
	 */
	public int Rob02(int[] nums) {

		// 边界条件处理
		if (null == nums || nums.length == 0){
			return 0;
		}

		int length = nums.length;
		// 第一家 没偷
		int dp0 = 0;
		// 第一节偷了
		int dp1 = nums[0];

		for (int i = 1; i < length; i++) {
			int temp =  Math.max(dp0, dp1);
			dp1 = dp0 + nums[i];
			dp0 = temp;
		}
		return Math.max(dp0, dp1);

	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值