【二叉树】【动态规划】1、斐波那契数+2、零钱兑换

1、遍历:在遍历的过程中就能够解决问题,只需要递归函数的参数即可。
2、子树:只有在遍历完成之后才能解决问题,还需要递归函数的返回值。(需要在后序位置写代码)

动态规划:子树 核心思想是穷举求最值
动态规划三要素:

正确的状态转移方程
具有最优子结构
存在重叠子问题(暴力穷举效率很低,需要使用备忘录(dp table)来优化穷举过程)

明确状态,明确选择,定义dp数组
回溯算法:树枝
DFS算法:节点

1、斐波那契数(难度:简单)

在这里插入图片描述

该题对应力扣网址

AC方法和对应代码

1、暴力递归穷举
重复计算太多
时间复杂度是O(2的n次方)

class Solution {
public://暴力递归穷举int fib(int n) {if(n==0 || n==1){return n;}return fib(n-1)+fib(n-2);}
};

2、带备忘录的递归解法
使用备忘录数组或者字典(这里用的数组)来记录每次已经算过的fib(n),避免重复计算
时间复杂度是O(n)

class Solution {
public://带备忘录的递归解法int fib(int n) {int nums[n+1];memset(nums,-1,sizeof(nums));return dp(nums, n);}int dp(int nums[], int n){if(n==0 || n==1){nums[n]=n;}//备忘录if(nums[n]!=-1){return nums[n];}return dp(nums,n-1)+dp(nums,n-2);}
};

3、dp数组的迭代(递推)解法(for循环)
前面两种方法都是自顶向下,然后最后通过返回值将答案返回给上级,本质上是自顶向下的思路。
这种方法是自底向上,仍然使用备忘录(数组)来辅助完成推算。
(注意:声明一个n+2的数组int dp[n+2],因为dp[0]=0,dp[1]=1,当n<2的时候,不这么定义会出现数组下标溢出的情况。)

class Solution {
public:int fib(int n) {int dp[n+2];dp[0]=0;dp[1]=1;for(int i=2;i<=n;i++){dp[i]=dp[i-1]+dp[i-2];}return dp[n];}
};

以上斐波那契数的题目也不算严格意义上的动态规划题目,只因为涉及到重叠子问题的消除。

暴力解的优化方法是用备忘录或者dp table
斐波那契数还有优化方法,可以将时间复杂度降为o(1)
把dp table的大小从n缩小到n

2、零钱兑换(难度:中等)

(看不懂啊看不懂,狗头保命)
在这里插入图片描述
该题对应力扣网址

动态规划递归模板

# 自顶向下递归的动态规划
def dp(状态1, 状态2, ...):for 选择 in 所有可能的选择:# 此时的状态已经因为做了选择而改变result = 求最值(result, dp(状态1, 状态2, ...))return result

动态规划迭代模板

# 自底向上迭代的动态规划
# 初始化 base case
dp[0][0][...] = base case
# 进行状态转移
for 状态1 in 状态1的所有取值:for 状态2 in 状态2的所有取值:for ...dp[状态1][状态2][...] = 求最值(选择1,选择2...)

超出时间限制

由于重复计算,导致超时严重。。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {return dp(coins,amount);}//状态是amount,即本题中的变量//选择:能够使状态发生变化,本题中指的是不同面值的硬币及个数//dp函数,函数参数包含状态,函数返回值是题目需要计算的值int dp(vector<int>& coins, int amount){if(amount==0){return 0;}if(amount<0){return -1;}int res=INT_MAX;//对所有可能的选择for(int coin: coins){int subsum=dp(coins,amount-coin);if(subsum==-1)continue;res=min(res,subsum+1);}return res==INT_MAX?-1:res;}
};

AC代码(递归+备忘录)

设置一个dp数组来作为备忘录
写的时候出现了两个问题:
1、备忘录数组的初始化问题,memset(memo,-1,sizeof(memo))用这个初始化方法初始化后不对~~(原理我之后再补)~~
2、一开始加上备忘录之后还是超时,后来发现备忘录数组其实和最后的res是一个值,所以应该放在返回值的地方再确定备忘录数组的值。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {//定义一个备忘录// int memo[amount+1]={-2};int* memo = new int[amount + 1];for (int i = 0; i <= amount; ++i) {memo[i] = -2;}// memset(memo,-1,sizeof(memo));// cout<<"尺寸:"<<sizeof(memo)<<endl;// cout<<"初始化:"<<memo[0]<<endl;return dp(memo,coins,amount);}//int dp(int memo[], vector<int>& coins, int amount){if(amount==0){return 0;}if(amount<0){return -1;}if(memo[amount]!=-2){return memo[amount];}int subsum;int res=INT_MAX;for(int coin: coins){// if(amount-coin>=0 && memo[amount-coin]!=-2){//     res=memo[amount-coin];// }subsum=dp(memo,coins,amount-coin);if(subsum==-1)continue;res=min(res,subsum+1);}if(res==INT_MAX){res=-1;}memo[amount]=res;return res;}
};

AC代码(迭代+dp数组)

看完题解了解完主要思路之后,终于把这个代码复现下来了,发现代入具体例子之后,才懂了在什么地方求最小值等等。
做的时候有个地方,就是int+int超出了数据范围报错,于是改成了相减amount-i-coin,解决了超限问题。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {//迭代+dp数组int *dp = new int[amount+1];//base case dp[0]for(int j=1;j<=amount;j++){dp[j]=-1;}dp[0]=0;int res=INT_MAX;//进行状态转移//循环所有的状态1,原递归的参数for(int i=0;i<=amount;i++){//循环所有状态2for(int coin:coins){if(dp[i]==-1)continue;res=dp[i]+1;if((amount-i-coin)<0)continue;if(dp[i+coin]!=-1){dp[i+coin]=min(res,dp[i+coin]);}else{dp[i+coin]=res;}//dp[1]=dp[0]+1=1//dp[2]=dp[0]+1=1//dp[5]=dp[0]+1=1//dp[1+1]=dp[2]=dp[1]+1=2//dp[1+2]=dp[3]=dp[1]+1=2//dp[1+5]=dp[6]=dp[1]+1=2//dp[2+1]=dp[3]=dp[2]+1=3//dp[2+2]=dp[4]=dp[2]+1=3//dp[2+5]=dp[7]=dp[2]+1=3//...//dp[6+5]=dp[6]+1=3//例如://dp[2]=1=2}}return dp[amount];}
};

从二叉树过来的,听说二叉树的思路可以延伸出来动态规划和回溯等算法,动态规划看了好几天的讲解,现在还是迷糊,费老大劲根据题解写完了两道题,总算有点思路了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/46474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【electron】 快速启动electron 应用

学无止境&#xff1a; 最近在搞electron项目&#xff0c;最重要的是总结 &#xff0c;写下来总不会忘记&#xff0c;也希望给大家参考一下&#xff0c;有不对的地方希望大家多指点。 快速启动electron 应用 1 克隆示例项目的仓库 git clone https://github.com/electron/ele…

Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBase 正在 章节内容 上一节我们完成了&#xff1a; 集群的…

从安装Node到TypeScript到VsCode的配置教程

从安装Node到TypeScript到VsCode的配置教程 1.下载Node安装包&#xff0c; 链接 2.双击安装包&#xff0c;选择安装路径&#xff0c;如下&#xff1a; 3.一直点击下一步&#xff0c;直至安装结束即可&#xff1a; 这个时候&#xff0c;node会默认配置好环境变量&#xff0c;并且…

java文本比较解决方案

参考资料 VBA计算页码和行号https://learn.microsoft.com/zh-cn/office/vba/api/word.wdinformation 概述&#xff1a; 最近在做word文档对比的&#xff0c;总结了几种解决方案&#xff0c;记录一下 在java中&#xff0c;常用的文本对比方案有如下几种&#xff1a; 差异比较…

Linux网络——套接字与UdpServer

目录 一、socket 编程接口 1.1 sockaddr 结构 1.2 socket 常见API 二、封装 InetAddr 三、网络字节序 四、封装通用 UdpServer 服务端 4.1 整体框架 4.2 类的初始化 4.2.1 socket 4.2.2 bind 4.2.3 创建流式套接字 4.2.4 填充结构体 4.3 服务器的运行 4.3.1 rec…

rabbitmq生产与消费

一、rabbitmq发送消息 一、简单模式 概述 一个生产者一个消费者模型 代码 //没有交换机&#xff0c;两个参数为routingKey和消息内容 rabbitTemplate.convertAndSend("test1_Queue","haha");二、工作队列模式 概述 一个生产者&#xff0c;多个消费者&a…

如何将PDF转换成可以直接编辑的CAD图纸?

PDF图纸是为了让用户更好的阅览CAD文件&#xff0c;但是&#xff0c;当我们想要对其进行编辑的时候&#xff0c;PDF图纸就是一个麻烦了。那么PDF转换成CAD后可以编辑吗&#xff1f;如何将PDF转换成可以直接编辑的CAD图纸呢&#xff1f;本篇给你答案。 1、启动迅捷CAD编辑器&…

【python学习】爬虫中常使用的urllib和requests库的的背景、定义、特点、功能、代码示例以及两者的区别

引言 urllib是Python标准库中的一个模块&#xff0c;它提供了一系列用于操作URL的功能 requests是一个Python第三方库&#xff0c;由Kenneth Reitz创建&#xff0c;用于简化HTTP客户端的编程 一、urllib的定义 urllib可以操作url&#xff0c;主要分为以下几个子模块&#xff1…

从人工巡检到智能防控:智慧油气田安全生产的新视角

一、背景需求 随着科技的飞速发展&#xff0c;视频监控技术已成为各行各业保障安全生产、提升管理效率的重要手段。特别是在油气田这一特殊领域&#xff0c;由于其工作环境复杂、安全风险高&#xff0c;传统的监控方式已难以满足实际需求。因此&#xff0c;基于视频监控AI智能…

ROS2从入门到精通2-3:机器人3D物理仿真Gazebo与案例分析

目录 0 专栏介绍1 什么是Gazebo&#xff1f;2 Gazebo架构2.1 Gazebo前后端2.2 Gazebo文件格式2.3 Gazebo环境变量 3 Gazebo安装与基本界面4 搭建自己的地图4.1 编辑地图4.2 保存地图4.3 加载地图 5 常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底…

CSS技巧专栏:一日一例 8 - 纯CSS利用mask属性实现按钮边框对称包围特效

CSS技巧专栏:一日一例 8 - 纯CSS利用mask属性实现按钮边框对称包围特效 上篇作业解题 在前一篇文章的最后,给各位看官留了一个作业,如上图所示。本篇文章,我们来公布一下它的源码。 主要实现的思路 四个渐变色的线段,沿着四个方向的依次运动,(运动在加载前执行)使用 …

均值滤波算法及实现

均值滤波器的使用场景&#xff1a; 均值滤波器使用于处理一些如上述蓝色线的高斯噪声场景 红色曲线是经过均值滤波处理后的数据。主要因为均值滤波设置数据缓冲区&#xff08;也即延时周期&#xff09;&#xff0c;使得测量值经过缓冲不会出现特别大的变化。 黄色曲线为高斯噪声…

【iOS】—— 消息传递和消息转发

【iOS】—— 消息传递和消息转发 1. 消息传递SEL选择子IMP快速查找汇编代码查找过程总结消息转送快速查找IMP 慢速查找总结消息传递慢速查找IMP 2. 消息转发动态决议动态解析添加方法 快速转发慢速转发 总结动态决议消息转发消息的三次拯救 1. 消息传递 在iOS中&#xff0c;消…

一、单例模式

文章目录 1 基本介绍2 实现方式2.1 饿汉式2.1.1 代码2.1.2 特性 2.2 懒汉式 ( 线程不安全 )2.2.1 代码2.2.2 特性 2.3 懒汉式 ( 线程安全 )2.3.1 代码2.3.2 特性 2.4 双重检查2.4.1 代码2.4.2 特性 2.5 静态内部类2.5.1 代码2.5.2 特性 2.6 枚举2.6.1 代码2.6.2 特性 3 实现的要…

谷粒商城-全文检索-ElasticSearch

1.简介 一个分布式的开源搜索和分析引擎,可以 秒 级的从海量数据中检索 主要功能:做数据的检索和分析(MySQL专攻于数据的持久化存储与管理CRUD达到百万以上的数据MSQL就会很慢,海量数据的检索和分析还是要用ElasticSearch) 用途:我们电商项目里的所有的检索功能都是由Elasti…

基于X86+FPGA+AI数字化医疗设备:全自动尿沉渣检测仪

助力数字医疗发展&#xff0c;信迈可提供全自动尿沉渣检测仪专用计算机 随着信息技术的不断进步&#xff0c;医疗也进入了一个全新的数字化时代。首先是医疗设备的数字化&#xff0c;大大丰富了医疗信息的内涵和容量&#xff0c;具有广阔的市场发展前景。 数字化医疗设备&…

使用Redis的SETNX命令实现分布式锁

什么是分布式锁 分布式锁是一种用于在分布式系统中控制多个节点对共享资源进行访问的机制。在分布式系统中&#xff0c;由于多个节点可能同时访问和修改同一个资源&#xff0c;因此需要一种方法来确保在任意时刻只有一个节点能够对资源进行操作&#xff0c;以避免数据不一致或…

嵌入式香橙派人工智能AI开发板详细操作与远程聊天实现

大家好&#xff0c;今天给大分享一个OrangePi AIpro&#xff08;20T&#xff09;采用昇腾作为主控芯片的开发板&#xff0c;开箱以及对应功能的详细实现。 第一&#xff1a;板子基本介绍 接通电源给对应的开发板上电&#xff0c;观察其中的现象&#xff0c;如下&#xff1a; 注…

基于HAL库的stm32的OLED显示屏显示(IIC)

OLED OLED&#xff0c;即有机发光二极管( Organic Light Emitting Diode )。OLED由于同时具备自发光&#xff0c;不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性&#xff0c;被认为是下一代的平面显示器…

龙国专利局瑞数6

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi a…