当前位置: 首页 > news >正文

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解题之前,可以看提示,但一定不要看题解,看了就“破功”了!

相关文章:

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

【题目描述】 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights &#xff0c;每个整数 互不相同&#xff0c;heights[i] 表示第 i 个人的高度。一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的&…...

Java基础面试题整理2024/3/13

1、可以使用switch的数据类型 Java5以前&#xff0c;switch(arg)表达式中&#xff0c;arg只能是byte、short、char、int。 Java5之后引入了枚举类型&#xff0c;也可以是枚举类型。 Java7开始引入了字符串类型。 2、Java中的goto有什么作用 goto是Java中的保留字&#xff0c…...

MachineSink - 优化阅读笔记

注&#xff1a;该优化与全局子表达式消除刚好是相反的过程&#xff0c;具体该不该做这个优化得看代价模型算出来的结果(有采样文件指导算得会更准确) 该优化过程将指令移动到后继基本块中&#xff0c;以便它们不会在不需要其结果的路径上执行。 该优化过程并非旨在替代或完全…...

虾皮shopee根据ID取商品详情 API

公共参数 名称类型必须描述keyString是免费申请调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认y…...

你知道数据库有哪些约束吗?

目录 1. NULL约束 2. 唯一&#xff08;UNIQUE&#xff09;约束 3. 默认值&#xff08;DEFAULT&#xff09;约束 4. 主键约束 5. 外键约束 6. CHECK约束 数据库约束是一种用于确保数据库中数据完整性和一致性的规则或条件。这些约束可以应用于表、列或整个数据库&#xff0…...

QT----基于QT的人脸考勤系统(未完成)

目录 1 编译opencv库1.1 下载源代码1.2 qt编译opencv1.3 执行Cmake一直卡着data: Download: face_landmark_model.dat 2 编译SeetaFace2代码2.1 遇到报错By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has2.2遇到报错Model missing 3 测试…...

机试:成绩排名

问题描述: 代码示例: #include <bits/stdc.h> using namespace std;int main(){cout << "样例输入" << endl; int n;int m;cin >> n;int nums[n];for(int i 0; i < n; i){cin >> nums[i];}// 排序for(int i 0; i < n; i){//…...

C编程基础四十分笔记

都是一些基础的C语言 一 输入一个整数&#xff0c;计算这个整数有几位二 编写程序计算一个分布函数三 输入一个字符串&#xff0c;再随便输入一个字母&#xff0c;判断这个字母出现几次四 求 1到10的阶乘之和五 求一个球体体积六 写一个链表&#xff0c;存1&#xff0c;2&#…...

k8s关于pod

目录 1、POD 的创建流程 kubectl 发起创建 Pod 请求&#xff1a; API Server 接收请求并处理&#xff1a; 写入 Etcd 数据库&#xff1a; Kubelet 监听并创建 Pod&#xff1a; Pod 状态更新和汇报&#xff1a; 2、POD 的状态解析 1. Pending Pod 2. Running Pod 3. S…...

yum安装mysql 数据库tab自动补全

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…...

MBT-Net

feature F&#xff0c;edge feature E-F where r related to the relative position 辅助信息 作者未提供代码...

大数据赋能,能源企业的智慧转型之路

在数字洪流中&#xff0c;大数据已经成为推动产业升级的新引擎。特别是在能源行业&#xff0c;大数据的应用正引领着一场深刻的智慧转型。今天&#xff0c;我们就来探讨大数据如何在能源企业中发挥其独特的魅力&#xff0c;助力企业提效降本&#xff0c;实现绿色发展。 动态监控…...

2024考研国家线公布,各科分数线有哪些变化?考研国家线哪些涨了,哪些跌了?可视化分析告诉你

结论在文章结尾 2024考研国家线 一、近五年国家线趋势图-学术硕士 文学 管理学 工学照顾专业 体育学 交叉学科 军事学 历史学 理学 享受少数名族照顾政策的考生 中医类照顾专业 教育类 艺术类 医学 工学 哲学 法学 农学 经济学 二、近五年国家线趋势图-专业硕士 中医 应用心理 …...

高效、安全的APP分发与推广平台

在信息化快速发展的今天&#xff0c;APP已经成为人们生活中不可或缺的一部分。然而&#xff0c;对于众多APP开发者来说&#xff0c;如何让自己的APP在众多竞争者中脱颖而出&#xff0c;被更多用户所认知和下载&#xff0c;成为了一个亟待解决的问题。这时&#xff0c;一个高效、…...

浅谈异或运算

异或&#xff0c;是一个数学运算符&#xff0c;英文为exclusive OR&#xff0c;缩写为xor&#xff0c;应用于逻辑运算。异或的数学符号为“⊕”&#xff0c;计算机符号为“xor”。其运算法则为&#xff1a; a⊕b &#xff08;a ∧ b&#xff09; ∨ &#xff08;a ∧b&#xf…...

Linux下platform总线

一. 简介 前面我们讲了设备驱动的分离&#xff0c;并且引出了总线 (bus) 、驱动 (driver) 和设备 (device) 模型&#xff0c;比如 I2C 、 SPI 、 USB 等总线。 但是&#xff0c;在 SOC 中有些外设是没有总线这个概念的&#xff0c;但是又要使用总 线、驱动和设备模型该怎么…...

C# EPPlus导出dataset----Excel2绘制图像

一、生成折线图方法 /// <summary> ///生成折线图 /// </summary> /// <param name="worksheet">sheet页数据 </param> /// <param name="colcount">总列数</param> /// &l…...

2024年云服务器ECS价格表出炉——阿里云

2024年阿里云服务器租用费用&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核4G服务…...

Grafana

介绍 官网&#xff1a;https://grafana.com/ Grafana 是一个开源的指标分析和可视化工具&#xff0c;它被广泛用于展示和监控云基础设施和应用程序的实时数据。Grafana 提供了一个强大且易于使用的界面&#xff0c;允许用户创建各种图表、图形和仪表盘&#xff0c;以直观地展…...

InnoDB记录结构

InnoDB页简介 InnoDB是一个将表中的数据存储到磁盘上的存储引擎&#xff0c;所以即使关机后重启我们的数据还是存在的。而真正处理数据的过程是发生在内存中的&#xff0c;所以需要把磁盘中的数据加载到内存中&#xff0c;如果是处理写入或修改请求的话&#xff0c;还需要把内…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程

基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...

表单设计器拖拽对象时添加属性

背景&#xff1a;因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...

C++ Saucer 编写Windows桌面应用

文章目录 一、背景二、Saucer 简介核心特性典型应用场景 三、生成自己的项目四、以Win32项目方式构建Win32项目禁用最大化按钮 五、总结 一、背景 使用Saucer框架&#xff0c;开发Windows桌面应用&#xff0c;把一个html页面作为GUI设计放到Saucer里&#xff0c;隐藏掉运行时弹…...

【Java基础】​​向上转型(Upcasting)和向下转型(Downcasting)

在面向对象编程中&#xff0c;转型&#xff08;Casting&#xff09; 是指改变对象的引用类型&#xff0c;主要涉及 继承关系 和 多态。 向上转型&#xff08;Upcasting&#xff09; ⬆️ 定义 将 子类对象 赋值给 父类引用&#xff08;自动完成&#xff0c;无需强制转换&…...

链结构与工作量证明7️⃣:用 Go 实现比特币的核心机制

链结构与工作量证明:用 Go 实现比特币的核心机制 如果你用 Go 写过区块、算过哈希,也大致理解了非对称加密、数据序列化这些“硬核知识”,那么恭喜你,现在我们终于可以把这些拼成一条完整的“区块链”。 不过别急,这一节我们重点搞懂两件事: 区块之间是怎么连接成“链”…...