两道算法练习
力扣322零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
示例 3:
输入: coins = [1], amount = 0
输出: 0
提示:
1 <= coins.length <= 121 <= coins[i] <= 231 - 10 <= amount <= 104
分析思路
- 分析子问题,当所有的子问题都是最优的时候总问题也就达到了最优。
- 分析最终状态,以示例1为例子:在选到5的时候刚好满足金额等于amount同时数量最优
- 分析去掉最后一个问题的状态:
它的子问题也就是:用最少得硬币数凑出 amount - 5 - 可以发现这个问题可以像递归搜索树一样进行拆分
- 又继续分析去掉倒数第二个问题的状态。
那么我们来分析代码:
const int N = 10010;class Solution
{int mem[N];int dfs(vector<int>& coins, int amount){if (mem[amount])return mem[amount];int res = 1e9;if (amount == 0)return 0;if (amount < 0)return 1e9;for (int i = 0; i < coins.size(); i++){if (amount >= coins[i])res = min(res, 1 + dfs(coins, amount - coins[i]));}mem[amount] = res;return res;}
public:int coinChange(vector<int>& coins, int amount){int n = coins.size();int ans = dfs(coins, amount);return ans == 1e9 ? -1 : ans;}
};
- 我们的思路就是让它凑出的每一个amount之前的数值都满足最小硬币的需求,那么当它递推到amount的时候,它的每一个子问题都是最优的,那么总问题就是最优的了。
for (int i = 0; i < coins.size(); i++){if (amount >= coins[i])res = min(res, 1 + dfs(coins, amount - coins[i]));}
-
我们不断地往下搜索,直到amount被减到0,其中每一个分支都进行了min的处理,所以当从下往上回溯的时候,返回的就是每个分支就小的情况也是每个子问题最优的情况。
-
所以我们可以这样想dp:
我们从凑出1块2块3块…知道amount块钱,每一次我们都考虑凑出的硬币数量最少,那么当我们推到amount的时候,不就是最优了吗?
class Solution
{
public:int coinChange(vector<int>& coins, int amount) {if (amount == 0)return 0;int n = coins.size();vector<int> dp(amount + 1, amount + 1);dp[0] = 0;for (int i = 1; i <= amount; i++){ for (int coin : coins){ if (i >= coin)dp[i] = min(dp[i], dp[i - coin] + 1);}}return dp[amount] > amount ? -1 : dp[amount]; }
};
- dp数组中的每个元素都被初始化为比amount大的数字,我们每次都更新凑得钱数所需硬币的最小值,从1凑到amount,这样到了amount的时候,就是最优的答案了
leetcode 413
如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
- 例如,
[1,3,5,7,9]、[7,7,7,7]和[3,-1,-5,-9]都是等差数列。
给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子数组 个数。
子数组 是数组中的一个连续序列。
示例 1:
输入: nums = [1,2,3,4]
输出: 3
解释: nums 中有三个子等差数组:[1, 2, 3]、[2, 3, 4] 和 [1,2,3,4] 自身。
示例 2:
输入: nums = [1]
输出: 0
提示:
1 <= nums.length <= 5000-1000 <= nums[i] <= 1000
1.
重述问题:找出数组中所有等差子数组的数量包括它本身
2.
最后一步:
-
以第
i个元素结尾的等差子数组数目,取决于当前差值是否与前一个差值相等。 -
如果相等,则以
i结尾的数目等于以i-1结尾的数目加 1
3.
去掉最后一步,是否能划分出子问题:
-
子问题划分:
-
如果当前差值与前一个差值相等,则
dp[i] = dp[i-1] + 1。 -
否则,
dp[i] = 0。
-
示例 1:
输入:nums = [1, 2, 3, 4]
我们需要找出所有长度至少为 3 的连续子数组,且这些子数组是等差数列。
-
子数组
[1, 2, 3]:差值为1,是等差数列。 -
子数组
[2, 3, 4]:差值为1,是等差数列。 -
子数组
[1, 2, 3, 4]:差值为1,是等差数列。
总共有 3 个等差子数组。
示例 2:
输入:nums = [1, 3, 5, 7, 9]
-
子数组
[1, 3, 5]:差值为2,是等差数列。 -
子数组
[3, 5, 7]:差值为2,是等差数列。 -
子数组
[5, 7, 9]:差值为2,是等差数列。 -
子数组
[1, 3, 5, 7]:差值为2,是等差数列。 -
子数组
[3, 5, 7, 9]:差值为2,是等差数列。 -
子数组
[1, 3, 5, 7, 9]:差值为2,是等差数列。
总共有 6 个等差子数组。
表格分析
我们可以通过表格来记录以每个位置结尾的等差子数组的个数。假设 dp[i] 表示以第 i 个元素结尾的等差子数组的个数。
示例 1:nums = [1, 2, 3, 4]
| 索引 (i) | 元素值 (nums[i]) | 差值 (nums[i] - nums[i-1]) | 前一个差值 (nums[i-1] - nums[i-2]) | dp[i](以 i 结尾的等差子数组个数) | 解释 |
|---|---|---|---|---|---|
| 0 | 1 | - | - | 0 | 长度不足 3,无法形成等差子数组。 |
| 1 | 2 | 1 | - | 0 | 长度不足 3,无法形成等差子数组。 |
| 2 | 3 | 1 | 1 | 1 | 差值相等,形成一个新的等差子数组 [1, 2, 3]。 |
| 3 | 4 | 1 | 1 | 2 | 差值相等,形成一个新的等差子数组 [2, 3, 4],并扩展 [1, 2, 3, 4]。 |
最终结果:dp[2] + dp[3] = 1 + 2 = 3。
示例 2:nums = [1, 3, 5, 7, 9]
| 索引 (i) | 元素值 (nums[i]) | 差值 (nums[i] - nums[i-1]) | 前一个差值 (nums[i-1] - nums[i-2]) | dp[i](以 i 结尾的等差子数组个数) | 解释 |
|---|---|---|---|---|---|
| 0 | 1 | - | - | 0 | 长度不足 3,无法形成等差子数组。 |
| 1 | 3 | 2 | - | 0 | 长度不足 3,无法形成等差子数组。 |
| 2 | 5 | 2 | 2 | 1 | 差值相等,形成一个新的等差子数组 [1, 3, 5]。 |
| 3 | 7 | 2 | 2 | 2 | 差值相等,形成一个新的等差子数组 [3, 5, 7],并扩展 [1, 3, 5, 7]。 |
| 4 | 9 | 2 | 2 | 3 | 差值相等,形成一个新的等差子数组 [5, 7, 9],并扩展 [3, 5, 7, 9] 和 [1, 3, 5, 7, 9]。 |
最终结果:dp[2] + dp[3] + dp[4] = 1 + 2 + 3 = 6。
if (diff == prev_diff)
{return helper(i-1, nums) + 1;
}
else
{return 0;
}
举例说明
示例:nums = [1, 2, 3, 4]
-
当
i = 2时:-
当前元素:
nums[2] = 3 -
差值:
diff = nums[2] - nums[1] = 3 - 2 = 1 -
前一个差值:
prev_diff = nums[1] - nums[0] = 2 - 1 = 1 -
判断:
diff == prev_diff成立。 -
递归调用:
helper(1, nums),由于i = 1不满足条件,返回 0。 -
结果:
helper(2, nums) = helper(1, nums) + 1 = 0 + 1 = 1。- 表示以
nums[2]结尾的等差子数组有 1 个,即[1, 2, 3]。
- 表示以
-
-
当
i = 3时:-
当前元素:
nums[3] = 4 -
差值:
diff = nums[3] - nums[2] = 4 - 3 = 1 -
前一个差值:
prev_diff = nums[2] - nums[1] = 3 - 2 = 1 -
判断:
diff == prev_diff成立。 -
递归调用:
helper(2, nums) = 1。 -
结果:
helper(3, nums) = helper(2, nums) + 1 = 1 + 1 = 2。-
表示以
nums[3]结尾的等差子数组有 2 个:-
[2, 3, 4] -
[1, 2, 3, 4]
-
-
-
const int N = 10010;
class Solution
{public://x表示当前以nums[x]为结尾的数组int dfs(int x, vector<int>& nums){if (x < 2)return 0;if (mem[x])return mem[x];int diff = nums[x] - nums[x - 1];int prv_diff = nums[x - 1] - nums[x - 2];if (diff == prv_diff){return mem[x] = dfs(x - 1, nums) + 1;}else{return 0;}}int mem[N];int numberOfArithmeticSlices(vector<int> &nums){int n = nums.size();if (nums.size() < 3)return 0;// vector<int> dp(n, 0);int res = 0;int prev = 0;// for (int i = 2; i < nums.size(); i++)// {// res += dfs(i, nums);// }// return res;for (int i = 2; i < nums.size(); i++){if (nums[i] - nums[i - 1] == nums[i - 1]- nums[i - 2]){// dp[i] = dp[i - 1] + 1;prev = prev + 1;res += prev;}}return prev;}
};
相关文章:
两道算法练习
力扣322零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的…...
利用 Python 爬虫进行跨境电商数据采集
1 引言2 代理IP的优势3 获取代理IP账号4 爬取实战案例---(某电商网站爬取)4.1 网站分析4.2 编写代码4.3 优化代码 5 总结 1 引言 在数字化时代,数据作为核心资源蕴含重要价值,网络爬虫成为企业洞察市场趋势、学术研究探索未知领域…...
设计模式--spring中用到的设计模式
一、单例模式(Singleton Pattern) 定义:确保一个类只有一个实例,并提供全局访问点 Spring中的应用:Spring默认将Bean配置为单例模式 案例: Component public class MySingletonBean {// Spring 默认将其…...
Qt控件中函数指针使用的最终版本,使用std::function
代码: class MyWidget : public QWidget { public:std::function<void(QResizeEvent* event)> pf_resizeEvent 0; protected:inline void resizeEvent(QResizeEvent* event) override {if (pf_resizeEvent ! 0)pf_resizeEvent(event);} };int main(int arg…...
Java中的泛型类 --为集合的学习做准备
学习目标 ● 掌握在集合中正确使用泛型 ● 了解泛型类、泛型接口、泛型方法 ● 了解泛型上下限 ● 了解基本的使用场景 1.有关泛型 1.1泛型的概念 泛型(Generics)是Java中引入的参数化类型机制,允许在定义类、接口或方法时使用类型参数&a…...
6.6.6 嵌入式SQL
文章目录 2个核心问题识别SQL语句主语言和SQL通信完整导图 2个核心问题 SQL语句嵌入高级语言需要解决的2个核心问题是:如何识别嵌入语句?如何让主语言(比如C,C语言)和SQL通信? 识别SQL语句 为了识别主语言中嵌入的SQL…...
基于C#的CANoe CLR Adapter开发指南
一、引言 CANoe 是一款广泛应用于汽车电子开发和测试的工具,它支持多种编程接口,方便开发者进行自定义扩展。CANoe CLR Adapter 允许我们使用 C# 语言与 CANoe 进行交互,充分利用 C# 的强大功能和丰富的类库。本文将详细介绍如何基于 C# 进行…...
【Qt】MVC设计模式
目录 一、搭建MVC框架 二、创建数据库连接单例类SingleDB 三、数据库业务操作类model设计 四、control层,关于model管理类设计 五、view层即为窗口UI类 一、搭建MVC框架 里面的bin、lib、database文件夹以及sqlite3.h与工程后缀为.pro文件的配置与上次发的文章…...
【手撕算法】支持向量机(SVM)从入门到实战:数学推导与核技巧揭秘
摘要 支持向量机(SVM)是机器学习中的经典算法!本文将深入解析最大间隔分类原理,手撕对偶问题推导过程,并实战实现非线性分类与图像识别。文中附《统计学习公式手册》及SVM调参指南,助力你掌握这一核心算法…...
JAVA面试常见题_基础部分_Dubbo面试题(上)
Dubbo 支持哪些协议,每种协议的应用场景,优缺点? • dubbo: 单一长连接和 NIO 异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议 TCP,异步,Hessian 序列化…...
CSS—隐藏元素:1分钟掌握与使用隐藏元素的方法
个人博客:haichenyi.com。感谢关注 1. 目录 1–目录2–display:none3–visibility: hidden4–opacity: 05–position: absolute;与 left: -9999px;6–z-index 和 position7–clip-path: circle(0%) 2. display:none 标签会挂载在html中,但是不会在页面上…...
二、双指针——5. 移动零
二、双指针——5. 移动零 题目描述示例示例1:示例2: 思路代码 题目描述 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操…...
论文笔记-NeurIPS2017-DropoutNet
论文笔记-NeurIPS2017-DropoutNet: Addressing Cold Start in Recommender Systems DropoutNet:解决推荐系统中的冷启动问题摘要1.引言2.前言3.方法3.1模型架构3.2冷启动训练3.3推荐 4.实验4.1实验设置4.2在CiteULike上的实验结果4.2.1 Dropout率的影响4.2.2 实验结…...
php 对接mqtt 完整版本,订阅消息,发送消息
首先打开链接如何在 PHP 项目中使用 MQTT 根据文章让所用依赖安装一下: composer require php-mqtt/client 安装之后弄一个部署 之后在工具里边可以相应链接上 接下来是代码: /**** 订阅消息* return void* throws \PhpMqtt\Client\Exceptions\Confi…...
谈谈 ES 6.8 到 7.10 的功能变迁(6)- 其他
这是 ES 7.10 相较于 ES 6.8 新增内容的最后一篇,主要涉及算分方法和同义词加载的部分。 自定义算分:script_score 2.0 Elasticsearch 7.0 引入了新一代的函数分数功能,称为 script_score 查询。这一新功能提供了一种更简单、更灵活的方式来…...
【苍穹外卖】问题笔记
【DAY1 】 1.VCS找不到 好吧,发现没安git 接着发现安全模式有问题,点开代码信任此项目 2.导入初始文件,全员爆红 好像没maven,配一个 并在设置里设置好maven 3.启用注解,见新手苍穹 pom.xml改lombok版本为1.1…...
脑机接口SSVEP 信号特征提取技术术语
目录 背景简介 1. 最小能量组合(MEC)和最大对比组合(MCC) 2. 典型相关分析(CCA) 3. 滤波器组CCA(FBCCA) 4. 二进制子带CCA(BsCCA) 5. 融合CCAÿ…...
【Veristand】Veristand 预编写教程目录
很久没有更新,最近打算出一期Veristand教程,暂时目录列成下面这个表格,如果各位有关心的遗漏的点,可以在评论区提问,我后期可以考虑添加进去,但是提前声明,太过小众的点我不会,欢迎各…...
C#光速入门的指南
以下是一份C#快速入门的指南,涵盖了基础语法、面向对象编程、输入输出、异常处理等方面,帮助你快速上手C#。 1. 开发环境搭建 要开始使用C#进行编程,你需要安装开发环境。最常用的是Visual Studio,它提供了丰富的工具和功能&…...
深入探索 STM32 微控制器:从基础到实践
一、引言 在当今的嵌入式系统领域,STM32 系列微控制器凭借其高性能、低功耗、丰富的外设以及广泛的应用场景,成为了众多开发者的首选。无论是在工业控制、智能家居、医疗设备,还是在消费电子等领域,STM32 都展现出了强大的生命力…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
