LeetCode-1944题: 队列中可以看到的人数(原创)

【题目描述】

        有 n 个人排成一个队列,从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights ,每个整数 互不相同,heights[i] 表示第 i 个人的高度。一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的,第 i 个人能看到第 j 个人的条件是 i < j 且 min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1]) 。请你返回一个长度为 n 的数组 answer ,其中 answer[i] 是第 i 个人在他右侧队列中能 看到 的 人数 。

【题目链接】. - 力扣(LeetCode)

【解题代码】

package array;import common.Utils;import java.util.Arrays;
import java.util.Stack;public class CanSeePersonsCount {public static void main(String[] args) {//int heights[] = {10, 6, 8, 5, 11, 9};//int heights[] = {5, 1, 2, 3, 10};int[] heights = Utils.readArrayFromFile("res\\1944\\40.txt");long start = System.currentTimeMillis();System.out.println("开始计算。。。");int[] result = canSeePersonsCount(heights);System.out.println("运行时长:" + (System.currentTimeMillis() - start) + "ms");System.out.println("计算结果:" + Arrays.toString(result));}public static int[] canSeePersonsCount(int[] heights) {int[] result = new int[heights.length];Stack<Integer> stack = new Stack<>();stack.push(heights[heights.length - 1]);for (int i = heights.length - 2; i >= 0; i--) {result[i] = 1;while (heights[i] > stack.peek()) {stack.pop();if (!stack.empty())result[i]++;else break;}stack.push(heights[i]);}return result;}}

【解题思路】

拿到题目,一开始想到的最简单思路就是位置i从0开始向后查找,设置一个数值max,记录当前最大身高,目前位置的人是否能被看到,取决于当前位置身高是否小于观测者并且大于max(没被挡住),一直轮询直到数值大于当前值的位置或者最后一个人为止,很快就完成代码编写

public int[] canSeePersonsCount1(int[] heights) {// 定义一个数组,记录所有位置能看到的人数int[] result = new int[heights.length];int max, j;for (int i = 0; i < heights.length - 1; i++) {// 从当前位置右边第一个位置开始计算j = i + 1;// 定义当前位置右边遍历的最大身高max = 0;// 向后依次轮询,直到数值大于当前值的位置为止do {// 如果当前位置身高大于当前最大身高,那么计数加1,并更新当前最大身高if (heights[j] > max) {result[i]++;max = heights[j];}} while (heights[j] < heights[i] && ++j < heights.length);}return result;
}

LeetCode试运行成果,看来逻辑正确,但这一道题毕竟是困难级别,这种两种循环的简单低级算法代码提交肯定不能通过,试了一下,果不其然,LeetCode系统报错:超出时间限制:

作为一个爱追根究底的程序员,我把LeetCode系统报错的测试用例的数据拷贝到一个文件里,然后,本地加载运行,看看到底需要运行多长时间,相关加载数据代码

public static int[] readArrayFromFile(String fileName) {StringBuffer sb = null;try {BufferedReader in = new BufferedReader(new FileReader(fileName));while (in.ready()) {sb = new StringBuffer(in.readLine());}} catch (Exception e) {return null;}String[] dataStrs = sb.toString().split(",");return Arrays.stream(dataStrs).mapToInt(Integer::parseInt).toArray();
}

本地执行一下,运行时长1656ms,肯定不合格。这只是简单热个身,接下来还是考虑专业的算法思路,看到代码页面下面有5个英文提示,翻译成中文如下:

  1. 如何以二次复杂度解决这个问题?-- 啥叫二次复杂度,哥们要的是提示,不是提问!
  2. 对于从索引 i 开始的每个子数组,不断查找新的最大值,直到找到大于 arr[i] 的值。--正确但无用的废话,以哥们的智商,这么简单的东西还要你来提示?
  3. 由于限制很高,因此您需要线性解决方案。--又是正确但无用的废话
  4. 当您从末尾到开头迭代数组时,使用堆栈来保持数组值的排序。--哎!堆栈!这个提示有搞头,继续看看下面怎么说。
  5. 继续按排序顺序从堆栈中弹出元素,直到找到大于 arr[i] 的值,这些是我可以看到的值。--这句的意思好像是每次看到的人,都是从堆栈依次弹出,一直到大于当前位置身高值

根据后面两个稍微有用的提示,反复思考终于有了眉目,几点思路总结如下:

  1. 最右一个人看到的人数是0,因为右边没人了;
  2. 其它位置能看到的人数至少是1,右边至少能看到1个人
  3. 其它位置向右看到的身高,肯定是一个比一个高,因为小于当前位置身高的,左边的人肯定看不到;
  4. 先将最右的人身高压栈
  5. 从最右边第二个位置开始,依次将栈中比当前身高矮的值出栈,然后将当前位置压栈
  6. 当前栈顶是右边第一个人身高,后面肯定是一个比一个高

思路一打开,解题就简单了,且看下面解题步骤

【解题步骤】

  1. 定义一个数组,记录所有位置能看到的人数
    int[] result = new int[heights.length];
  2. 定义一个堆栈,记录当前位置身高以及其右边“一个比一个高”的身高
    Stack<Integer> stack = new Stack<>();
  3. 将最右侧人身高压栈,最右侧的人看到的人数为0
    stack.push(heights[heights.length - 1]);
  4.  从最右边第二个位置开始,依次计算能看到的人数,当前位置至少能看到右侧紧挨着的这个人
    for (int i = heights.length - 2; i >= 0; i--) {result[i] = 1;

  5. 后从栈中弹出所有比当前位置身高矮的人,这些都是当前位置能看到的人,也都是左边位置都看不到的人
    while (heights[i] > stack.peek()) {stack.pop();if (stack.empty()) break;result[i]++;
    }
  6. 再将当前位置身高压栈,栈里此时状况是"一山还比一山高"
    stack.push(heights[i]);
  7. 最后返回结果
    return result;

【思考总结】

  1. 专业深入的思考之前,可以简单的方式实现热热身;
  2. LeetCode解题一个关键点就是,需要掌握相关调试工具和技巧,对于算法执行时间等性能指标要有清晰的数据;
  3. 这道题算法设计的关键点在于使用堆栈:以及保存当前位置右侧所有的一山还比一山高”的身高;
  4. LeetCode解题之前,可以看提示,但一定不要看题解,看了就“破功”了!

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

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

相关文章

能量不等式证明

波动方程初值问题能量不等式的证明 Gronwall 不等式 若非负函数 G ( τ ) G(\tau) G(τ) 在 [ 0 , T ] [0,T] [0,T] 上连续可微&#xff0c; G ( 0 ) 0 G(0)0 G(0)0&#xff0c;且对 τ ∈ [ 0 , T ] \tau\in[0,T] τ∈[0,T]满足 d G ( τ ) d τ ≤ C G ( τ ) F ( τ …

Flutter图片内存占用过大问题

图片(Image)加载原理&#xff1a; Image &#xff1a; 显示图⽚的Widget&#xff0c;通过ImageState管理ImageProvider的⽣命周期。 ImageProvider&#xff1a; 图⽚的抽象概念。 根据Image创建实例时调用的工厂方法的不同&#xff08;Image.network或者Image.assetImage&#…

【FPGA/IC】CRC电路的Verilog实现

前言 在通信过程中由于存在各种各样的干扰因素&#xff0c;可能会导致发送的信息与接收的信息不一致&#xff0c;比如发送数据为 1010_1010&#xff0c;传输过程中由于某些干扰&#xff0c;导致接收方接收的数据却成了0110_1010。为了保证数据传输的正确性&#xff0c;工程师们…

禁止使用搜索引擎,你了解吗?

员工A&#xff1a;“我今天想搜索的时候&#xff0c;用不了浏览器了&#xff0c;你能用么&#xff1f;” 员工B&#xff1a;“不知道啊我试一下啊” “也不行” 员工C&#xff1a;“为什么啊&#xff1f;” 针对上述对话&#xff0c;我们不禁思考&#xff1a; 公司为什么禁…

python基础9_序列类型

回顾: 什么是变量?,有什么用? 可以变化的量, 就是个容器,多次变化,方便后续使用, 前面介绍了哪些数据类型? bool, str, int, float 用什么函数查看数据的类型? a "hello" print(type(a)) 到了这一步,,我们认识了哪些数据类型呢? int 整型(整数), float…

office下常见问题总结——(持续更新学习记录中......)

目录 Wordword2019中, 当给选定的汉字设置格式后&#xff0c;其他相同汉字也会自动应用相同的格式?在Word中&#xff0c;当输入数字后加上句点&#xff08;.&#xff09;时会自动被识别为标题,如何关闭功能?如何让当前的word中的样式 ,匹配全局模版中的样式?在word中,为什么…

一、NLP中的文本分类

目录 1.0 文本分类的应用场景 1.1 文本分类流程 ​编辑 1.2 判别式模型 1.3 生成式模型 1.4 评估 1.5 参考文献 1.0 文本分类的应用场景 &#xff08;1&#xff09;情感分析&#xff1a;中性&#xff0c;正向评论&#xff0c;负向评论&#xff0c;黄色言论&#xff0c;暴…

Java基础 - 8 - 算法、正则表达式、异常

一. 算法 什么是算法&#xff1f; 解决某个实际问题的过程和方法 学习算法的技巧&#xff1f; 先搞清楚算法的流程&#xff0c;再直接去推敲如何写算法 1.1 排序算法 1.1.1 冒泡排序 每次从数组中找出最大值放在数组的后面去 public class demo {public static void main(S…

Matlab偏微分方程拟合 | 完整源码 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

力扣hot100题解(python版63-68题)

63、搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输…

【npm】前端工程项目配置文件package.json详解

简言 详细介绍了package.json中每个字段的作用。 package.json 本文档将为您介绍 package.json 文件的所有要求。它必须是实际的 JSON&#xff0c;而不仅仅是 JavaScript 对象文字。 如果你要发布你的项目&#xff0c;这是一个特别重要的文件&#xff0c;其中name和version是…

王升:Audio电感对车载功放EMC的影响 | 演讲嘉宾公布

一、智能车载音频 II 专题论坛 智能车载音频 II 专题论坛将于3月28日同期举办&#xff01; 我们正站在一个前所未有的科技革新的交汇点上&#xff0c;重塑我们出行体验的变革正在悄然发生。当人工智能的磅礴力量与车载音频相交融&#xff0c;智慧、便捷与未来的探索之旅正式扬帆…

若依/RuoYi-Vue使用docker-compose部署

系统需求 JDK > 1.8 MySQL > 5.7 Maven > 3.0 Node > 12 Redis > 3 思路 前端服务器 nginx 后端服务器代码打包 java、maven、node 数据库/缓存 mysql、redis 开始 创建目录ruoyi并进入 克隆若依代码 git clone RuoYi-Vue: &#x1f389; 基于Spring…

试用期自我总结报告10篇

试用期自我总结报告&#xff08;篇1&#xff09; 一转眼试用期的时间飞快就过去了&#xff0c;在这段时间里我学习到了很多&#xff0c;也把自己在过去学习的东西得已融会贯通。能够来到幼儿园里成为一名老师是我一直以来的目标&#xff0c;而我也终于完成了自己的目标&#x…

Winform窗体随着屏幕的DPI缩放,会引起窗体变形及字体变形,superTabControl标签字体大小不匹配

一、前言 superTabControl做的浏览器标签(cefsharp)在缩放比例(125%,150%时字体不协调) 物联网浏览器,定制浏览器,多媒体浏览器(支持H264)参考栏目文章即可 二、配置参数 app.manifest参数 dpiAware =true <application xmlns="urn:schemas-microsoft-c…

用 Axios 提升前端异步请求的效率

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ubuntu22.01安装及配置

前言 本次安装基于VMware Pro 16进行安装。 ubuntu版本&#xff1a;ubuntu-22.04.3-live-server-amd64.iso 1、下载 1.1官网下载 https://ubuntu.com/download 1.2、清华大学镜像网站下载 https://mirrors.tuna.tsinghua.edu.cn/ 进入网站后搜索ubuntu&#xff0c;选择ubu…

Claude3超大杯发布,将取代ChatGPT4?

演示站点&#xff1a; https://ai.uaai.cn 创作模块 &#xff08;Claude3已接入&#xff0c;欢迎体验&#xff09;官方论坛&#xff1a; www.jingyuai.com 前言 今天【超越GPT-4 接近人类水平&#xff01;Claude 3系列大模型惊艳问世】登上了全网热搜&#xff0c;那么【超…

微信小程序实现上拉加载更多

一、前情提要 微信小程序中实现上拉加载更多&#xff0c;其实就是pc端项目的分页。使用的是scroll-view&#xff0c;scroll-view详情在微信开发文档/开发/组件/视图容器中。每次上拉&#xff0c;就是在原有数据基础上&#xff0c;拼接/合并上本次上拉请求得到的数据。这里采用…

电动机工作原理图

电机&#xff08;俗称“马达”&#xff09;是指依据电磁感应定律实现电能转换或传递的一种电磁装置。它的主要作用是产生驱动转矩&#xff0c;作为用电器或各种机械的动力源。 电动机&#xff0c;转子置于旋转磁场中&#xff0c;在旋转磁场的作用下&#xff0c;获得一个转动力…