数据结构和算法-动态规划(3)-经典问题
动态规划常见问题
打家劫舍
题目
[力扣198] 198. 打家劫舍 - 力扣(LeetCode)
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 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 。
解决方案

边界条件
-
只有一间房子
if(nums.length==1) return nums[0];
-
有2间房子
if (nums.length == 2) return Math.max(nums[0],nums[1]);
一般情况
-
定义记忆化数组int[] , 记录每次偷窃成功的值。
int[] dp = new int[nums.length];
-
初始化dp(1间房子或两间房子)
dp[0] = nums[0]; dp[1] = Math.max(nums[0],nums[1]);
-
其它情况
- 当前盗取的第K个房间的结果与 前K-2 个有关
- 如果不选择盗取当前K,则与K-1有关
//状态转移方程 dp[K] = max(dp[K-2] + nums[K], dp[K-1]);
tips: 不能盗取相邻的房子
for (int i = 2; i < nums.length; i++) {dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); }
提交模版
class Solution {public int rob(int[] nums) {} }
参考实现
class Solution {public int rob(int[] nums) {// 定义dp数组,存储最优结果int[] dp = new int[nums.length];if (nums.length == 1) {return nums[0];}/** 边界条件: 只有两间房子*/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 - 2] + nums[i], dp[i - 1]);}return dp[dp.length - 1];} }
打家劫舍II
题目
[力扣213] 213. 打家劫舍 II - 力扣(LeetCode)
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
示例 1:
输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:
输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。
示例 3:
输入:nums = [1,2,3]
输出:3
解决方案

边界条件
-
只有一间房子
if(nums.length==1) return nums[0];
-
有2间房子
if (nums.length == 2) return Math.max(nums[0],nums[1]);
一般条件
提交模版
参考实现
class Solution {public int rob(int[] nums) {if (nums.length == 1) {return nums[0];} else if (nums.length == 2) {return Math.max(nums[0], nums[1]);} else {int a = robRange(nums, 0, nums.length - 1);int b = robRange(nums, 1, nums.length);return Math.max(a, b);}}public int robRange(int[] nums, int start, int end) {int[] a = Arrays.copyOfRange(nums,start, end);int pre = 0;int curr = 0;int tmp = 0;for(int i =0 ; i< a.length; i++){tmp = curr;curr = Math.max(pre + a[i], curr);pre = tmp;}return curr;}
}
子串问题
问题
两组字符串 X=“ATCTGAT”, Y= “TGCATA”, 找出相同的子字符串,且顺序不变Z=“TCAT”, 长度4。
分析
检查X,Y较小的字符串看看它们的最长子串,分成两类最后一个字符相同,最后一个字符不同
如果其中一个字符串为空
如果X,Y中任意一个字符串为空,那么不存在最长子串问题
最长子串 = 0 ; X,y的字符串为空
从较小的问题看-末尾不同
-
Y不变,看X的较小字符串"ATCTGA"
X = “ATCTGAT” 是由X1=“ATCTGA” 和“T"构成,看看X1 和Y的最大子串。“TCTA”
-
X不变, 看Y的较小字符串"TGCATA"
X=“ATCTGAT”, Y1=“TGCAT”,最大子串 “TCAT"
-
最大相同子串
假设X字符串当前的索引为 i;Y字符串的索引为j。
最大长度 = max(X之前的最大字符串, Y之前的字符串)
末尾相同

最长子串就是之前的最大子串+当前的相同字符
最大子串 = 之前的最大子串+1
解决方案
由分析可得,最大子串可以分为3中情况,使用int[][] dp数组记忆化步骤。
package com.ffyc.dp;public class SubString {public static void main(String[] args) {String x = "ATCTGAT";String y = "TGCATA";int len1 = x.length();int len2 = y.length();int result = 0;if(len1==0|| len2 ==0) result = 0;int[][] dp = new int[len1][len2];for(int i=0; i< len1;i++){for(int j =0; j<len2;j++){if(i!=0 && j!=0){if(x.charAt(i) == y.charAt(j)){dp[i][j] = dp[i-1][j-1]+1;}else{dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);}}else{dp[i][j] = x.charAt(i)== y.charAt(j) ? 1 :0;}}}result = dp[len1-1][len2-1];System.out.println(result);}
}
买卖股票
买卖股票的最佳时机
题目
[力扣121] 121. 买卖股票的最佳时机 - 力扣(LeetCode)
描述
给定一个数组 prices
,它的第 i
个元素 prices[i]
表示一支给定股票第 i
天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
解决方案

有两个因素影响股票价格
-
当天不卖,前一天的股票最大价格
dp[d] = dp[d-1]; //d表示当天
-
当天卖出某一天买入的最小价格,比如上周五买最低,本周二卖
dp[d] = price[d]- min(dp[从开始--当天的最小值]);
动态转移方程
dp[i] = max(dp[i-1], price[i]-min(dp[从开始--当天的最小值]));
提交模版
class Solution {public int maxProfit(int[] prices) {}
}
参考实现
class Solution {public int maxProfit(int[] prices) {int n = prices.length;if (n < 2)return 0;int[] dp = new int[n];int min = prices[0];for(int i=1; i < n;i++){dp[i] = Math.max(dp[i-1], prices[i]-min);min = Math.min(min, prices[i]);}return dp[n-1];}
}
买卖股票的最佳时机II
问题
[力扣122]122. 买卖股票的最佳时机 II - 力扣(LeetCode)
问题描述
给你一个整数数组 prices
,其中 prices[i]
表示某支股票第 i
天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。
最大总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
最大总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。
解决方案
当天i, 有两种最大股票利润的状态,
- 持有此股票的最大利润
- 不持有此股票的最大利润
用二维数组创建记录数组: dp[天][是否持有股票] —0:不持有股票, 1:持有股票
tips: 可以当天买入当天卖出
-
当天不持有
-
前一天卖出,不持有
dp[i-1][0]
-
前一天买入,当天卖出,不持有,今天就可以盈利
dp[i-1][1]+prices[i];
-
-
当天持有
-
前一天买入
dp[i-1][1];
-
前一天没有,当天买入,减去今天花费的成本
dp[i-1][0]-price[i];
-
参考实现
class Solution {public int maxProfit(int[] prices) {int n = prices.length;if(n < 2) return 0;int[][] dp = new int[n][2];dp[0][1] = 0- prices[0]; //当天成为买入成本for(int i=1; i<n;i++){dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]+prices[i]);dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);}return dp[n-1][0];}
}
相关文章:

数据结构和算法-动态规划(3)-经典问题
动态规划常见问题 打家劫舍 题目 [力扣198] 198. 打家劫舍 - 力扣(LeetCode) 题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&…...

Java算法-一维前缀和与差分
一、一维前缀和 ① 什么是一维前缀和? 📚 其实通过名字就能知道" 一维前缀和 "的意思: 通过一个一维数组"arr1"而创建的另一个一维数组"arr2","arr2"的每一个元素都是"arr1"…...

Elasticsearch 安装教程:驾驭数据海洋的星际导航仪
目录 一、准备工作1. ES的下载 二、安装步骤三、注意事项四、启动报错1. org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root2. max virtual memory areas vm.max_map_count [65530] is too low, increase to at l…...

【解决方案】微信小程序如何使用 ProtoBuf 进行 WebSocket 通信
前言 故事背景 简单说下背景,项目中需要用 ProtoBuf 协议转换请求参数,并通过 WebSocket 进行双向通信。重点!一个是 web端(Vue3 TS),一个是微信小程序端(原生 JS)。 剧情发展 …...

独立游戏开发者面临的挑战与困境
在当今竞争激烈的游戏市场中,独立游戏开发者面临着诸多挑战与困境。从游戏版号申请到游戏被抄袭,再到产品同质化以及流量获取难题,乃至外包内卷现象,每一个环节都考验着开发者的智慧与毅力。以下是对这些挑战与闲境的详细分析。 …...

KVM 虚拟机Anolis OS 8.9 下利用宝塔面板中的 Docker 配置 Nextcloud + onlyoffice
第一部分:安装配置 nextcloud 准备 (1)启动一个 Anolis OS 8.9 虚拟机,见下图。该虚拟机为 anlisos8…0.2 虚拟机的 ssh、hostname 、IP地址都已配置好。 (2)宝塔面板也已安装好docker 一、环境 do…...
串口扫盲TTL,TX/TR/GND
1. 串口扫盲TTL,TX/TR/GND 1. 串口扫盲TTL,TX/TR/GND 1.1. TTL1.2. USB转TTL1.3. 串口通信1.4. 引脚缩写1.5. 参考资料 1.1. TTL TX(TXD) 来源于 Transmit 一词,意思为发送,发射RX(RXD) 来源于 Receive 一词 意思为接收,收到GND 地线&…...

Python酷库之旅-第三方库Pandas(181)
目录 一、用法精讲 836、pandas.api.types.is_file_like函数 836-1、语法 836-2、参数 836-3、功能 836-4、返回值 836-5、说明 836-6、用法 836-6-1、数据准备 836-6-2、代码示例 836-6-3、结果输出 837、pandas.api.types.is_list_like函数 837-1、语法 837-2、…...

Python数据分析NumPy和pandas(十七、pandas 二进制格式文件处理)
以二进制格式存储(或序列化)数据的一种简单方法是使用 Python 的内置 pickle 模块。同时,pandas 构造的对象都有一个 to_pickle 方法,该方法以 pickle 格式将数据写入磁盘。 我们先把之前示例用到的ex1.csv文件加载到pandas对象中…...
matlab计算相关物理参数
function Rx1Jetfire1_1(di,Ct,Tf,Tj,alpha,Ma,Mf,RH,P0,P,k,Cd,elta,deltaHc,tau,directory) % 一共15个独立变量,为了方便输入修改,所有变量存入Jetfire1_1excel表, % dj为孔口直径,m;Ct为燃料空气混合摩尔系数,可…...
nmcli、ip、ifcfg配置网络区分方法
文章目录 一、检查NetworkManager状态使用nmcli命令:检查NetworkManager服务状态: 二、检查ip命令的使用三、检查ifcfg文件查看/etc/sysconfig/network-scripts/目录:查看/etc/network/interfaces文件(针对Debian系)&a…...

第四届智能电力与系统国际学术会议(ICIPS 2024)
文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网:https://ais.cn/u/vEbMBz提交检索:EI Compendex、IEEE Xplore、Scopus 三、大会介绍 四、出席嘉宾 五、征稿主题 如想"投稿…...
区块链样题第4套解析 后端应用开发部分
任务3-2:区块链应用后端开发 使用JAVA-SDK与区块链进行交互,通过solc2Java工具将Solidity智能合约转译为可供Java调用的文件,实现区块链编程。 前言:题目只是单纯考了对于fisco-java-sdk的简单使用 教程参考: 1.这边建议还是学习完JavaWeb课程。 黑马程序员JavaWeb...

C语言实现408考研真题2016年43题
#include <iostream> // 定义分区函数,返回两个子数组之和的差值 int setPartition(int a[], int n) { int pivotkey, low 0, low0 0, high n - 1, high0 n - 1, flag 1, k n / 2, i; int s1 0, s2 0; // 当low等于k-1,…...

2024年,Rust开发语言,现在怎么样了?
Rust开发语言有着一些其他语言明显的优势,但也充满着争议,难上手、学习陡峭等。 Rust 是由 Mozilla 主导开发的通用、编译型编程语言,2010年首次公开。 在 Stack Overflow 的年度开发者调查报告中,Rust 连续多年被评为“最受喜爱…...
三种网络配置方法nmcli、ip、ifcfg文件
文章目录 总结nmcli配置网络定义与功能:特点:示例: ip配置网络定义与功能:特点:示例: ifcfg配置网络定义与功能:特点:示例: 总结 nmcli:适合需要动态管理网络…...
AES_ECB算法C++与Java相互加解密Demo
一、AES算法 AES是一种对称加密算法,算法秘钥长度可为128位(16字节)、192位(24字节)、256位(32字节)。加密模式分为ECB、CBC、CTR等,其中ECB模式最简单够用。现给出ECB模式下C和Java的实现,并且可以相互加解密验证。 二、AES_ECB实现DEMO …...

H7-TOOL自制Flash读写保护算法系列,为兆易创新GD32E23X制作使能和解除算法,支持在线烧录和脱机烧录使用(2024-10-29)
说明: 很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。 实际上当前已经发布的TOOL版本,已经自制很多了。但是依然有些厂家还没自制,所以陆续开始…...
FFmpeg 深度教程音视频处理的终极工具
1. 引言 什么是 FFmpeg? FFmpeg 是一个开源的跨平台多媒体处理工具,广泛应用于音视频的录制、转换、流式传输以及编辑等多个领域。它由 FFmpeg 项目团队开发和维护,支持几乎所有主流的音视频格式和编解码器。FFmpeg 包含了一系列强大的命令…...

Java程序设计:spring boot(13)——全局异常与事务控制
1 Spring Boot 事务支持 在使⽤ Jdbc 作为数据库访问技术时,Spring Boot框架定义了基于jdbc的PlatformTransaction Manager 接⼝的实现 DataSourceTransactionManager,并在 Spring Boot 应⽤ 启动时⾃动进⾏配置。如果使⽤ jpa 的话 Spring Boot 同样提供…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...