动态规划/贪心算法

一、动态规划

动态规划 是一种用于解决优化问题的算法设计技术,尤其适用于具有重叠子问题和最优子结构性质的问题。它通过将复杂问题分解为更简单的子问题,并保存这些子问题的解以避免重复计算,从而提高效率。

动态规划的核心思想

  1. 最优子结构(Optimal Substructure)

    • 一个问题的最优解可以通过其子问题的最优解来构造。
    • 比如在最短路径问题中,从起点到终点的最短路径可以由起点到某个中间点的最短路径和该中间点到终点的最短路径组合而成。
  2. 重叠子问题(Overlapping Subproblems)

    • 在递归求解过程中,相同的子问题会被多次求解。
    • 动态规划通过存储子问题的解来避免重复计算,通常使用数组或哈希表等数据结构来存储这些解。

1.算法原理

1)状态表示

dp表(一维数组  填满该表其中某一个值就是结果 数组中某个数据值的意义就是状态表示)

通过题目要求 经验  分析问题发现重复子问题 来创建dp表

2)状态转移方程

dp[i]等于什么?

3)初始化

根据状态转移方程填表,保证填表的时候不越界

4)填表顺序

为了填写当前状态的时候,所需要的状态已经计算过了

5)返回值

题目要求+状态表示

2.例题

泰波那契序列 Tn 定义如下: 

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

示例 1:输入:n = 4 输出:4    解释: T_3 = 0 + 1 + 1 = 2 T_4 = 1 + 1 + 2 = 4

状态表示:dp[i]第i个泰波那契数的值

状态转移方程:dp[i]=dp[i-1]+dp[i-2]+dp[i-3];

初始化:dp[0]=0;dp[1]=1;dp[2]=1

填表顺序:从左向右

返回值:dp[n]

JAVA代码

class Solution {public int tribonacci(int n) {
if(n==0) return 0;
if(n==1||n==2) return 1;
int[] dp=new int[n+1];
dp[0]=0;dp[1]=1;dp[2]=1;
for(int i=3;i<=n;i++){dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
}
return dp[n];}
}

3.空间优化

求解某个状态时仅需要其的前几个状态

一定要确定好赋序

int tribonacci(int n){
//空间优化 滚动数组
if(n==0) return 0;
if(n==1||n==2) return 1;
int a=0;int b=1,c=1;int d=0;
for(int i=3;i<=n;i++){d=a+b+c;a=b;b=c;c=d;}
return d;
}

 二、贪心算法

1.算法原理:

局部最优->全局最优

把解决问题的过程分为若干步,解决每一步的时候都选择当前看起来最优的解

希望得到全局最优解

但贪心算法并不总是保证全局最优解

2.例题

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

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

在数组中挑出两个数,使其差值最大

1)暴力解法(两层for循环) 超出时间限制时间复杂度O(n^2)

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;class Solution {public int maxProfit(int[] prices) {int ret = 0;if (prices == null || prices.length < 2) {return 0;}for (int i = 0; i < prices.length - 1; i++) {for (int j = i+1; j < prices.length; j++) {ret = Math.max(ret, prices[j] - prices[i]);}}return ret;}public static void main(String[] args) {Scanner sc=new Scanner(System.in);Solution solution=new Solution();List<Integer> pricesList = new ArrayList<>();while (sc.hasNextInt()) {pricesList.add(sc.nextInt());}int[] prices = new int[pricesList.size()];for (int i = 0; i < pricesList.size(); i++) {prices[i] = pricesList.get(i);}int ret=solution.maxProfit(prices);System.out.println(ret);sc.close();}
}//在输入结束后输入一个非数字字符(如字母 'q'),这样 hasNextInt() 会返回 false,从而结束循环,或 Ctrl + Z(Windows)来发送 EOF 信号。

2)贪心

分为两段,prevmin表示前一段中最小值(买入),prices[i]卖出去的价钱

class Solution {public int maxProfit(int[] prices) {int ret=0;for(int i=0,prevmin=Integer.MAX_VALUE;i<prices.length;i++){ret=Math.max(ret,prices[i]-prevmin);prevmin=Math.min(prevmin,prices[i]);}return ret;}
}

三、 (双指针算法)

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

数组划分

利用数组下标充当指针 

两个指针的作用:

cur:从左往右扫描,遍历数组

dest:已处理的区间内,非0元素的最后一个位置

三个区间:

[0,dest]   [dest+1,cur-1]  [cur,n-1]

非0         0元素                 待处理的区间

解法:

初始dest=-1 cur=0

遇到0元素,cur++;

遇到非0元素 swap(dest+1,cur)交换位置 dest++ cur++

class Solution {public void moveZeroes(int[] nums) {
int dest=-1;
int cur=0;
int k=0;
int n=nums.length;
while(cur<n){
if(nums[cur]==0)
cur++;
else
{dest++;
k=nums[dest];
nums[dest]=nums[cur];
nums[cur]=k;
cur++;
}}}
}

 

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

输入: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 。

利用数组下标充当指针(i,j)

class Solution {public int maxProfit(int[] prices) {//双指针算法int ret=0;int i=0,j=0;for(i=0;i<prices.length;i++){j=i;while(j+1<prices.length && prices[j+1]-prices[j]>0){j++;}ret+=prices[j]-prices[i];i=j;}return ret;}
}

四、递归

1.什么是递归

函数自己调用自己(主问题->相同的子问题)

出口(一个问题不能在分割了)           

1.算法思想

函数头 函数体 递归出口

把递归的函数当成一个黑盒,不在意递归的细节

深度优先遍历(后序遍历)

2.例题

计算布尔二叉树的值

给你一棵 完整二叉树 的根,这棵树有以下特征:

  • 叶子节点 要么值为 0 要么值为 1 ,其中 0 表示 False ,1 表示 True 。
  • 非叶子节点 要么值为 2 要么值为 3 ,其中 2 表示逻辑或 OR ,3 表示逻辑与 AND 。

计算 一个节点的值方式如下:

  • 如果节点是个叶子节点,那么节点的  为它本身,即 True 或者 False 。
  • 否则,计算 两个孩子的节点值,然后将该节点的运算符对两个孩子值进行 运算 。

返回根节点 root 的布尔运算值。

完整二叉树 是每个节点有 0 个或者 2 个孩子的二叉树。

叶子节点 是没有孩子的节点。

class Solution {public boolean evaluateTree(TreeNode root) {if(root.left==null) return root.val==0 ? false: true;boolean left=evaluateTree(root.left);boolean right=evaluateTree(root.right);return root.val==2 ?left | right : left & right;}
}

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

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

相关文章

【实战篇】【深度解析DeepSeek:从机器学习到深度学习的全场景落地指南】

一、机器学习模型:DeepSeek的降维打击 1.1 监督学习与无监督学习的"左右互搏" 监督学习就像学霸刷题——给标注数据(参考答案)训练模型。DeepSeek在信贷风控场景中,用逻辑回归模型分析百万级用户数据,通过特征工程挖掘出"凌晨3点频繁申请贷款"这类魔…

软考中级-数据库-3.2 数据结构-数组和矩阵

数组 一维数组是长度固定的线性表&#xff0c;数组中的每个数据元素类型相同。n维数组是定长线性表在维数上的扩张&#xff0c;即线性表中的元素又是一个线性表。 例如一维数组a[5][a1,a2,a3,a4,a5] 二维数组a[2][3]是一个2行2列的数组 第一行[a11,a12,a13] 第二行[a21,a22,a23…

android亮灭屏流程分析

前言 亮灭涉及的东西非常多&#xff0c;因此单独写一个文档&#xff0c;进行详细说明&#xff0c;亮灭屏包括的东西不只是亮灭屏&#xff0c;还包括亮度调节、屏幕状态变化等东西。本文仅作学习使用&#xff0c;不涉及商业&#xff0c;侵权请联系删除。 framework层的学习链接…

V4L2框架基础

一、V4L2视频设备驱动基础 1.V4L2是专门为Linux设备设计的整合视频框架&#xff08;其主要核心在Linux内核&#xff0c;相当于Linux操作系统上层的视频源捕获驱动框架&#xff09;。为上层访问系统底层的视频设备提供一个统一的标准接口。V4L2驱动框架能够支持多种类型&#x…

C# 多线程

概述 进程和线程 进程&#xff1a;指在系统中运行的一个应用程序。 线程&#xff1a;进程中的一个执行任务。一个进程至少有一个线程&#xff0c;一个进程可以有多个线程&#xff0c;多个线程可共享数据。 多线程 多线程&#xff1a;在一个程序中同时运行多个线程&#xff0…

突破光学成像局限:全视野光学血管造影技术新进展

全视野光学血管造影&#xff08;FFOA&#xff09;作为一种实时、无创的成像技术&#xff0c;能够提取生物血液微循环信息&#xff0c;为深入探究生物组织的功能和病理变化提供关键数据。然而&#xff0c;传统FFOA成像方法受到光学镜头景深&#xff08;DOF&#xff09;的限制&am…

Deepgram推出Nova-3 Medical,AI语音转录助力医疗行业

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

centOS 环境 安装redis方法

一、准备centOS环境 参考文章&#xff1a;Hyper-V 安装CentOS7_代码草率了的博客-CSDN博客 二、redis官网 地址&#xff1a;Download | Redis 演示版本为?redis-5.0.14.tar.gz 三、redis源码编译 登录后创建soft目录 进入目录使用wget下载所需资源包 命令&#xff1a;w…

[51 单片机] --串口编程

1&#xff0c;通讯方式基本概念 1&#xff0c;按照 --> 数据传送方式串行通讯&#xff1a;使用一条数据线&#xff0c;将数据一位一位地依次传输&#xff0c;每一位数据占据一个固定的时间长度&#xff0c;串行通信的特点&#xff1a;传输线少&#xff0c;长距离传送时成本…

Golang的微服务服务发现机制

## 1. Golang微服务服务发现机制 微服务架构已经成为当今软件开发的主流趋势&#xff0c;它能将复杂的单体应用拆分成小而独立的服务单元&#xff0c;实现更快的开发、部署和扩展。在微服务架构中&#xff0c;服务发现是非常重要的一环&#xff0c;它能够实现服务之间的自动发现…

Python 创建地形图

原始地 DEM。 火山口湖 (OR) 区域的起始 DEM。数据来自 NASA DEM 本身非常美丽&#xff0c;但我们先进行分层。 将自定义色彩图应用于 DEM 对于我在 ArcGIS Pro 版本中所做的初始高程样式着色&#xff0c;我使用了“高程 #7”。在 matplotlib 中可用的标准颜色图中&#xff…

《Operating System Concepts》阅读笔记:p180-p187

《Operating System Concepts》学习第 20 天&#xff0c;p180-p187 总结&#xff0c;总计 8 页。 一、技术总结 1.forke-join A strategy for thread creation in which the main parent thread creates (forks) one or more child threads and then waits for the children…

文心4.5,大模型下半场的野心之作

2025年开年&#xff0c;全球大模型竞赛进入白热化阶段。2月28日&#xff0c;百度宣布其文心大模型4.5将于3月16日正式上线&#xff0c;强调其原生多模态与深度思考能力&#xff0c;并计划于6月30日开源。这一动作不仅标志着百度技术路线的重大转向&#xff0c;更被视为中国大模…

transformer架构解析{前馈全连接层,规范化层,子层(残差)连接结构}(含代码)-4

目录 前言 前馈全连接层 学习目标 什么是前馈全连接层 前馈全连接层的作用 前馈全连接层代码实现 规范化层 学习目标 规范化层的作用 规范化层的代码实现 子层&#xff08;残差&#xff09;连接结构 学习目标 什么是子层&#xff08;残差&#xff09;连接结构 子层连…

Django视图与URLs路由详解

在Django Web框架中&#xff0c;视图&#xff08;Views&#xff09;和URLs路由&#xff08;URL routing&#xff09;是Web应用开发的核心概念。它们共同负责将用户的请求映射到相应的Python函数&#xff0c;并返回适当的响应。本篇博客将深入探讨Django的视图和URLs路由系统&am…

串口通讯基础

第1章 串口的发送和接收过程 1.1 串口接收过程 当上位机给串口发送(0x55)数据时&#xff0c;MCU的RX引脚接受到&#xff08;0x55&#xff09;数据&#xff0c;数据(0x55)首先进入移位寄存器。数据全部进入移位寄存器后&#xff0c;一次将&#xff08;0x55&#xff09;全部搬运…

kakfa-3:ISR机制、HWLEO、生产者、消费者、核心参数负载均衡

1. kafka内核原理 1.1 ISR机制 光是依靠多副本机制能保证Kafka的高可用性&#xff0c;但是能保证数据不丢失吗&#xff1f;不行&#xff0c;因为如果leader宕机&#xff0c;但是leader的数据还没同步到follower上去&#xff0c;此时即使选举了follower作为新的leader&#xff…

基于Linux系统的物联网智能终端

背景 产品研发和项目研发有什么区别&#xff1f;一个令人发指的问题&#xff0c;刚开始工作时项目开发居多&#xff0c;认为项目开发和产品开发区别不大&#xff0c;待后来随着自身能力的提升&#xff0c;逐步感到要开发一个好产品还是比较难的&#xff0c;我认为项目开发的目的…

STM32——DMA详解

目录 一&#xff1a;DMA简介 二&#xff1a;DMA基本结构 三&#xff1a;DMA实现过程 1.框图 2.DMA进行转运的条件 四&#xff1a;函数 一&#xff1a;DMA简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设存储器或者存储器和存储器之间的高速数据传输&…

告别卡顿,拥抱流畅!MemReduct——内存清理工具

先给安装包下载地址&#xff1a;MemReduct.exe下载&#xff0c;无脑下一步安装即可。 MemReduct 是一款出色的内存清理工具&#xff0c;以下是对它的详细介绍&#xff1a; 功能特点 高效内存清理&#xff1a;采用先进算法及系统底层 API&#xff0c;能智能清理系统缓存、应用…