java算法day23

java算法day23

  • 121买卖股票的最佳时机
  • 55 跳跃游戏
  • 45 跳跃游戏Ⅱ
  • 763划分子母区间

121买卖股票的最佳时机

最容易想的应该就是两个for暴力枚举。但是超时

本题用贪心做应该是最快的。
先看清楚题,题目要求在某一天买入,然后在某一天卖出,要求利润最大。因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。

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

最主要的就是minValue不断的在维护左边的最小值,而maxValue = Math.max(maxValue,prices[i]-minValue);会在遍历的过程中,不断往右的过程中,不断的去探索最大值,所以这样就满足了贪心的思想。

真觉得没必要动态规划。


55 跳跃游戏

贪心的核心思路:
问题转化为跳跃覆盖范围究竟可不可以覆盖到终点。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。

既然要找覆盖范围,那么扫过来每一个点都不能放过。由于只能在范围之内走动,所以循环条件多了一个i<=cover,但又不能超过数组总长,因此还有一个nums.length。
每到一个点就更新该点所能跳到的覆盖范围,每个点的覆盖范围的计算就是i+nums[i]。但是这个cover,要取最大范围,如果每到一个点用当前点的cover,那么就有可能漏结果。因此一定要是维护最大范围。

一旦发现cover大于等于nums.length-1即覆盖范围达到了最后一个元素,那么返回true。如果循环结束了都没返回true,那么就是不可能达到。

class Solution {public boolean canJump(int[] nums) {if(nums==null || nums.length==0){return false;}int cover = 0;for(int i = 0;i<=cover && i<nums.length;i++){cover = Math.max(cover,i+nums[i]);if(cover>=nums.length-1){return true;}}return false;}
}

45 跳跃游戏Ⅱ

这个题和跳跃游戏思维差不多,这里我还是再总结思想。
一定要跳出某一步能不能到达某个位置这种思想。而是应该在遍历中,去寻找某一步所能走出的最大范围。

比如从第一步开始,确定了第一步能够走到的最大范围,那么我们需要做的是,在这个第一步的最大范围内,找到往后覆盖的最大范围。那么i一直往后走,这个时候我们知道i能往后走,但是不关注从哪里跳的,所以没有必要去定位要到哪个地方才能跳到下一个位置。因为对于上一个题(跳跃游戏)而言,题目并不是关注要到哪个地方跳,而是问能不能到。对于本题而言,再每一步中找到下一步所能覆盖到的最大范围,当i走完第一步覆盖的范围,那么此时就必须要走下一步了,还是同理,我们根本就不关注是从哪个地方走的下一步,只是知道我们要走出第一步的范围,那么肯定是要走下一步的。所以可以判断出,如果当前位置到了当前步的最大位置,那么步数肯定要+1了,因为下一个区域是走第二步之后才能到达的区域。

现在来看代码怎么写:
1.关键变量:
curDistance:当前这“一步”能够达到的最远距离
nextDistance:下一步可能到达的最远距离。
ans:跳跃次数

(1)遍历数组,对于每个位置i,都要去更新nextDistance,即“下一步”可能到达的最远位置。
(2)如果i到达了curDistance,当前这一步到达的最远距离,如果curDistance不是数组末尾,那么就要增加跳跃次数,更新curDistance为nextDistance。
如果curDistance是数组末尾,提前break,结束循环。还有一个快速特判,nextDistance已经可以到达数组末尾,提前结束循环。

3.特殊条件,当i==curDistance时我们需要觉得是否再跳一次,如果curDistance不是数组末尾,那么就要再跳一次,如果是那就不需要跳了。

贪心思想:
我们总是贪心地选择当前可以到达的最远距离,然后在这个范围内找下一个最远距离。这样,我们可以保证用最少的跳跃次数到达终点。

class Solution {  public int jump(int[] nums) {  if (nums.length == 1) {  return 0;  }  int curDistance = 0;  // 当前覆盖的最远距离下标  int nextDistance = 0; // 下一步覆盖的最远距离下标  int jumps = 0;        // 跳跃次数  //不处理最后一个位置,因为那个位置没必要走。for (int i = 0; i < nums.length - 1; i++) {  // 更新下一步可以覆盖的最远距离  //因为一开始curDistance=0,所以要先更新,不然下一步没法走nextDistance = Math.max(nextDistance, i + nums[i]);  // 走的过程中看看是否到了“当前步的最远”if (i == curDistance) {  //到了当前步最远就要进行跳跃了,jumps++;                 // 进行跳跃  curDistance = nextDistance; // 更新当前覆盖的最远距离  // 先看看这个覆盖距离,如果已经能到最后一个位置,那么直接break了。//也就是在这一步中肯定能到末尾。  if (curDistance >= nums.length - 1) {  break;  }  }  }  return jumps;  }  
}

763划分字母区间

题目意思翻译:
段数尽可能多,每一段中保证同一子母最多出现在一个段中。


这个题我建议是理解后记一下思路:
暴力做法就是回溯,这个题如果是回溯,那么就是切割字符串问题。然后对切好的字符串进一步进行题意的判断。但是这就太麻烦了。

贪心做法:

在做之前还要告搞懂一个问题:那么如何把同一个字母的都圈在同一个区间里呢?
做法:
1.遍历统计每一个字符最后出现的位置
2.从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

在这里插入图片描述

我只能说这个解法真的很神奇。我是从模拟的角度来看这个算法的:

1.每个子串是从当前未处理的第一个字符开始的。

2.然后,我们不断地"扩展"这个子串,直到包含了所有需要包含的字符。

3.这个"扩展"过程是通过查看每个字符的最后出现位置来实现的。如果我们在扩展过程中遇到了一个字符,它的最后出现位置比我们当前考虑的结束位置更靠后,我们就需要进一步扩展子串。

4.当我们遍历到的位置恰好等于当前考虑的结束位置时,我们就找到了一个可以安全划分的点。

5.然后我们就可以开始处理下一个子串,重复这个过程。


这个方法之所以如此巧妙,是因为它利用了问题的特性:

我们必须把每个字符的所有出现都包含在同一个子串中。
我们想要尽可能多的划分(即尽可能多的子串)

通过只向前看(即只考虑字符的最后出现位置),我们可以在一次遍历中得到最优解,这看起来就是通过局部最优的选择,最终达到全局最优。

class Solution {public List<Integer> partitionLabels(String S) {List<Integer> list = new LinkedList<>();//用于记录每个子母最后出现的位置int[] edge = new int[26];char[] chars = S.toCharArray();//遍历字符串s,扫描完之后记录了对应子母最后出现的位置。for (int i = 0; i < chars.length; i++) {edge[chars[i] - 'a'] = i;}int idx = 0;//当前子串的结束位置int last = -1;//上一个子串的结束位置//再次遍历字符串s,这里使用双指针for (int i = 0; i < chars.length; i++) {idx = Math.max(idx,edge[chars[i] - 'a']);if (i == idx) {list.add(i - last);last = i;}}return list;}
}

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

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

相关文章

MarkTool集合篇

MarkTool目前包含以下几种工具 1、TCP客户端 2、TCP服务端 3、UDP客户端 4、Web客户端 5、Web服务端 6、串口网口 7、PLC 8、获取本机设备 9、Log 10、密钥 11、系统设置 11-1、基本设置 11-2、角色设置 11-3、用户设置 11-4、log记录 开启软件需要找我解密&#…

S7-1200PLC通过111报文和EPOS模式实现位置轴轴控功能(FB284封装)

EASY_SINA_POS的详细使用介绍请参考下面文章链接: S7-1200PLC使用标准报文111和EPOS模式实现V90 PN总线伺服定位(Easy_SINA_Pos)_西门子sinapos-CSDN博客文章浏览阅读132次。文章浏览阅读7k次。先简单说下如何获取FB284,一般有2种方法,Startdrive软件可以操作大部分西门子的…

PostgreSQL使用(四)——数据查询

说明&#xff1a;对于一门SQL语言&#xff0c;数据查询是我们非常常用的&#xff0c;也是SQL语言中非常大的一块。本文介绍PostgreSQL使用中的数据查询&#xff0c;如有一张表&#xff0c;内容如下&#xff1a; 简单查询 --- 1.查询某张表的全部数据 select * from tb_student…

【Qt】QLabel常用属性相关API

QLabel是Qt框架中用于显示文本或图案的小部件。在Qt应用程序中&#xff0c;QLabel是用来呈现静态文本或图像给用户的重要部分 QLabel属性陈列 属性说明textQLabel中的文本内容textFormat 文本的格式 Qt::PlainText 纯文本Qt::RichText 富文本Qt::MarkdownText markdown…

管理和监控 Oracle 数据库中的会话和进程,以及终止特定的会话

select username,count(username) from v$session where username is not null group by username;• 作用: 统计每个用户的当前会话数量。 • 介绍: 从 v$session 视图中选择 username 和 username 的计数&#xff0c;并对不为空的 username 进行分组。 SELECT sid, serial#,…

IntelliJIDEA------简介

IntelliJ IDEA 14是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE支 持、Ant、JUnit、CVS整合、代码审查、 创新的GUI设计等方面的功能可以说是超常的。 IntelliJ IDEA特色功能 IDEA所提倡的…

【数据结构】排序算法(冒泡排序、插入排序、希尔排序、选择排序、堆排序、计数排序)

生命不可能有两次&#xff0c;但许多人连一次也不善于度过。&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;排序的概念和应用 • &#x1f330;1.排序及其概念 • &#x1f330;2.排序的应用 • &#x1f330;3.常见的排序算…

php 箭头函数详解

PHP 的箭头函数&#xff08;也称为匿名函数或闭包函数&#xff09;是一种简洁的定义单表达式函数的方法。这种语法是从 PHP 7.4 版本开始引入的&#xff0c;它使得创建简短的一次性使用的函数变得更加方便。 基本语法 箭头函数的基本语法如下&#xff1a; fn($parameters) &…

qt做的分页控件

介绍 qt做的分页控件 如何使用 创建 Pagination必须基于一个QWidget创建&#xff0c;否则会引发错误。 Pagination* pa new Pagination(QWidget*);设置总页数 Pagination需要设置一个总的页数&#xff0c;来初始化页码。 pa->SetTotalItem(count);设置可选的每页数量…

前端养成记-实现一个低配版简单版本的vue3表单自定义设计组件

简介&#xff1a; 通过使用了最新的vue3,vite2,TypeScript等主流技术开发&#xff0c;并配合使用vuedraggable 插件以及antd design vue 组件库实现低配版本的自定义表单设计组件&#xff1b; 项目地址&#xff1a;https://gitee.com/hejunqing/vue3-antdv-generator

PyTorch模型训练步步详解:从零开始构建深度学习流程

P y T o r c h 训练模型流程图 PyTorch训练模型流程图 P y T orc h 训练模型流程图

Python面试宝典第20题:精选问答题

题目1 解释Python中的GIL是什么&#xff0c;它是如何影响多线程程序的&#xff1f; 题目2 Python中的装饰器是什么&#xff0c;如何定义和使用一个装饰器&#xff1f; 题目3 Python中的迭代器和生成器有什么区别&#xff0c;并提供一个使用生成器的例子。 题目4 谈一谈你对Pyth…

非凸T0算法,如何获取超额收益?

什么是非凸 T0 算法&#xff1f; 非凸 T0 算法基于投资者持有的股票持仓&#xff0c;利用机器学习等技术&#xff0c;短周期预测&#xff0c;全自动操作&#xff0c;抓取行情波动价差&#xff0c;增厚产品收益。通过开仓金额限制、持仓时长控制等&#xff0c;把控盈亏风险&…

学习笔记:MySQL数据库操作5

1. 触发器&#xff08;Triggers&#xff09; 触发器是数据库的一种高级功能&#xff0c;它允许在执行特定数据库操作&#xff08;如INSERT、UPDATE、DELETE&#xff09;之前或之后自动执行一段代码。 1.1 创建商品和订单表 商品表&#xff08;goods&#xff09; gid: 商品编号…

会话存储、本地存储,路由导航守卫、web会话跟踪、JWT生成token、axios请求拦截、响应拦截

1、会话存储、本地存储 前端浏览器中存储用户信息&#xff0c;会话存储、本地存储、cookie 会话存储&#xff08;sessionStorage&#xff09;&#xff1a;会话期间存储&#xff0c;关闭浏览器后&#xff0c;数据就会销毁 sessionStorage.setItem("account",resp.d…

反射型与dom型的xss的区别【源码分析】

反射型 XSS 和 DOM 型 XSS 都属于跨站脚本攻击 (XSS) 的类型&#xff0c;它们的共同点是均能通过注入恶意脚本在用户浏览器中执行&#xff0c;不同点是dom型xss不经过服务器&#xff0c;而反射型是经过服务器的。但是&#xff0c;它们在攻击方式、执行过程和防御措施上有所不同…

flask后端+vue前端——后端怎么发文件给前端?

首先&#xff0c;前端axios请求的responseType要设置为blob const service axios.create({baseURL: http://127.0.0.1/api,timeout: 5000});//向后端发送数据&#xff0c;后端根据这个数据data生成文件返回send_coordinate(data){return service.post(/,data,{responseType: …

c++栈笔记

一种常见的数据结构&#xff0c;遵循后进先出&#xff0c;先进后出的原则。地址不连续&#xff0c;栈顶&#xff08;top&#xff09; 1.常见函数 stack<int> s;定义一个参数类型为int 的栈 名为ss.push()向栈中插入元素s.emplace()压栈&#xff0c;无返回值s.pop()删除…

@SpingFrameWork

SpingFrameWork 一、技术体系结构 单一架构&#xff0c;一个大的项目&#xff0c;一个工程&#xff0c;导出war包在一个tomcat上运行&#xff08;主要用spring、springMVC、Mybatis&#xff09;分布式架构&#xff0c;一个项目&#xff0c;但是有多个模块&#xff0c;但是每个…

摆脱想得太多做得太少的困境,拥抱财富与成功

在生活的舞台上,我们常常目睹这样的场景:有些人怀揣着美好的梦想和周全的计划,却始终未能迈出实质性的步伐,最终被困顿的现状所束缚。就如同那位卖豆腐的人,每日在夜里为自己编织着绚烂的未来蓝图,却在黎明来临时,依旧重复着昨日卖豆腐的生活,一辈子在原地徘徊,无法挣…