算法46:动态规划专练(力扣198: 打家劫舍 力扣740:删除并获取点数)

news/2024/10/22 14:41:27/

打家劫舍问题

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

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

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

分析:

这一题看起来是隔一家偷一家的问题。其实不是那么回事。它和爬楼梯花费最小代价是一个性质的题目.

a.  只有1户人家,没到选; 2户人家偷钱多的。

b. 如果是 3户人家,那就要看偷的钱数的累加和了。假设数组为: [2,3,4]. 偷的最大金额就是 2+4 =6;中间隔一家

c. 假设是4户人家 : [3,2,4,10]. 

数值32410
下标0123
偷窃最大金额33713

     偷窃的最大金额是13.

package code04.动态规划专项训练01;/*** 力扣198题 : 打家劫舍问题* https://leetcode.cn/problems/house-robber/?envType=study-plan-v2&envId=dynamic-programming*/
public class Rob_05 {public int rob(int[] nums){if (nums == null || nums.length == 0) {return 0;}//只有1间房if (nums.length == 1) {return nums[0];}//2间房,偷金额大的if (nums.length == 2) {return Math.max(nums[0], nums[1]);}int n = nums.length;//动态规划,普遍现象就是dp表长度要多1个。int[] dp = new int[n];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < nums.length; i++) {dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);}return dp[n-1];}public static void main(String[] args) {// int[] arr ={2,1,1,2};//  int[] arr ={1,7,9,4};int[] arr ={1,2,3,1};Rob_05 ss = new Rob_05();System.out.println(ss.rob(arr));}
}

   

力扣740:删除并获取点数

给你一个整数数组 nums ,你可以对它进行一些操作。

每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。

开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。

示例 1:

输入:nums = [3,4,2]
输出:6
解释:
删除 4 获得 4 个点数,因此 3 也被删除。
之后,删除 2 获得 2 个点数。总共获得 6 个点数。

示例 2:

输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。

这一题很好玩,可以借鉴词频统计的思想。之前我写过关于词频统计的博客,有兴趣的可以翻一翻。

a. 这一题可能会出现重复值的问题。而且如果我们选取了值为3的元素,那就得把2和4的值都给删除掉了。

b. 词频统计的思想,一旦字母固定,那么在数组中的位置也就固定了。同样的道理,一旦值固定,我们创新新的数组,用这个值对应新数组的下标,那么这个值对应的下标也就固定了。

以[2,2,3,3,3,4] 举例子

转变后数组变成了

无重复数组:                          [0, 1, 2, 3, 4] 

根据无重复数组,算的累加和 [0, 0, 4, 9, 4]

 为什么数组长度为4 ?

根据元素数组的最大值确定数组长度。

package code04.动态规划专项训练01;/*** 力扣 740 : 删除并获取点数*  https://leetcode.cn/problems/delete-and-earn/description/?envType=study-plan-v2&envId=dynamic-programming*/
public class DeleteAndEarn_06
{public int deleteAndEarn(int[] nums) {//边界值if (nums == null || nums.length == 0) {return 0;}//只有1个数if (nums.length == 1) {return nums[0];}//找出最大值int max = 0;for(int i = 0; i < nums.length; i++) {max = Math.max(max, nums[i]);}//这一点不好,根据数组的最大值,确定辅助数组的长度int size = max + 1;//统计出每个值出现的点数int[] ss = new int[size];for (int i = 0; i < nums.length; i++) {//词频统计的思路,每个字母出现对应的ASSC码不变//本题中,重复值出现的话,ss数组的下标志值也不会改变,但是点数会累加ss[nums[i]] += nums[i];}//dp表放置的是逐个数出现的最大值。它是随着数组个数的变化而逐渐变化的// 数组为1,那最大值就为1.//数组为 {1,2}, 那最大值就为2//数组为{1,2,4}. 那最大值就是 2+ 4 = 6.int[] dp = new int[ss.length];dp[0] = ss[0];dp[1] = ss[0] >= ss[1] ? ss[0] : ss[1];for (int index = 2; index < ss.length; index++) {//ss[i]就是有序的,它的排序是按照原始数组的值进行排序的。//原始数组一旦选定num[i], 还得考虑num[i]-1 和 num[i]+1 的问题// 经过转换:// num[i]-1 就变成了 index -1;//当前只遍历到 index,不存在 num[i]+1 即 index + 1的情况dp[index] = Math.max(dp[index-1], dp[index-2] + ss[index]);}return dp[max];}public static void main(String[] args) {//int[] arr = {3,4,2};//int[] arr = {3,1};int[] arr = {1,1,1,2,4,5,5,5,6};DeleteAndEarn_06 ss = new DeleteAndEarn_06();System.out.println(ss.deleteAndEarn(arr));}
}

本道题是数据量可能有限,我看测试是通过了,并设 85%的胜率也还算不错了。

但是,这一题确定新数组长度的思想是按照数组最大值确定的。假设数组为 [2,2,3,3,100万], 难到你的新数组长度要定义成100万?

离散化技巧 : 在说线段树的时候,我多次使用过离散化的技巧。并且专门分析过:算法41:掉落的方块(力扣699题)----线段树-CSDN博客

这一题,我觉得使用离散化技巧去确定新数组的长度更合适,具体我就不去尝试了,感谢的可以尝试一下


http://www.ppmy.cn/news/1372480.html

相关文章

Ubantu 18.04 如何映射IP到公网,外网可以访问

介绍一种简单的方式&#xff0c;就是通过路由侠 inux 系统安装路由侠&#xff0c;可通过两种方式进行&#xff0c;一种是通过直接脚本安装&#xff0c;一种是通过 Docker 安装。 windows下载地址&#xff1a;路由侠-局域网变公网 方式一&#xff1a;通过脚本安装 1、获取安…

数据库原理及应用 第四章:关系数据库标准查询语音SQL

文章目录 四、关系数据库标准查询语音SQL4.0SQL语言概述4.1基本表的定义4.2查询结果显示4.3查询满足条件的元组4.4分组聚集查询4.5连接查询4.6嵌套查询 四、关系数据库标准查询语音SQL 4.0SQL语言概述 4.1基本表的定义 char和varchar的区别&#xff1a;当输入的字符不足n个字符…

【排序算法】深入理解归并排序算法:从原理到实现

目录 1. 引言 2. 归并排序算法原理 3. 归并排序的时间复杂度分析 4. 归并排序的应用场景 5. 归并排序的优缺点分析 5.1 优点&#xff1a; 5.2 缺点&#xff1a; 6. Java、JavaScript 和 Python 实现归并排序算法 6.1 Java 实现&#xff1a; 6.2 JavaScript 实现&…

请说明Vue中的异步组件加载

Vue中的异步组件加载是指当页面需要渲染某个组件时&#xff0c;可以在需要时再去加载这个组件&#xff0c;而不是在页面初始化的时候就将所有组件一次性加载进来。这种方式能够有效降低页面的初始加载时间&#xff0c;提升用户体验。 在Vue中&#xff0c;我们可以使用import函…

可以设置提醒的电脑桌面便签备忘录软件哪个好用?

对于我们职场人来说&#xff0c;每天的时间都很紧张且有价值&#xff0c;如何有效地利用它们&#xff0c;让时间不被浪费流逝掉&#xff0c;成为越来越多的人在思考的一个问题。为了有效管理时间以及各项待办事务&#xff0c;一些人会使用可以设置提醒的电脑桌面便签备忘录软件…

小程序 API 能力汇总——TYML IntersectionObserver API

ty.createIntersectionObserver 创建并返回一个 IntersectionObserver 对象实例。在自定义组件或包含自定义组件的页面中&#xff0c;应使用 this.createIntersectionObserver([options]) 来代替。 使用方式 ty.createIntersectionObserver(instance, [options]); this.cre…

mac电脑版MATLAB R2023b for Mac中文激活版

MATLAB R2023b for Mac&#xff1a;科学计算的终极工具 软件下载&#xff1a;MATLAB R2023b for Mac中文激活版下载 &#x1f52c; 探索科学&#xff0c;无限可能 MATLAB R2023b for Mac&#xff0c;助您深入挖掘科学计算的奥秘。从数据分析、算法设计到可视化展示&#xff0c;…

hive实战项目:旅游集市数仓建设

旅游集市数仓建设 文章目录 旅游集市数仓建设为什么要设计数据分层&#xff1f;分层设计ODS&#xff08;Operational Data Store&#xff09;&#xff1a;数据运营层DW&#xff08;Data Warehouse&#xff09;&#xff1a;数据仓库层DWD&#xff08;Data Warehouse Detail&…