ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-12-06 22:35:15  阅读:183  来源: 互联网

标签:偷窃 nums int 32 金额 length 算法 打家劫舍 dp


学习目标:

本次学习目标为 力扣初级算法-动态规划,其中主要的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);

	}

标签:偷窃,nums,int,32,金额,length,算法,打家劫舍,dp
来源: https://blog.csdn.net/nvluco/article/details/121757064

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

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

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

ICode9版权所有