大厂秋招真题【单调栈】Bilibili2021秋招-大鱼吃小鱼

文章目录

  • 题目描述与示例
    • 题目描述
    • 输入描述
    • 输出描述
    • 示例一
      • 输入
      • 输出
      • 说明
    • 示例二
      • 输入
      • 输出
      • 说明
  • 解题思路
  • 代码
    • Python
    • Java
    • C++
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目描述与示例

题目描述

小明最近喜欢上了俄罗斯套娃、大鱼吃小鱼这些大的包住小的类型的游戏。

于是小明爸爸给小明做了一个特别版的大鱼吃小鱼游戏,他希望通过这个游戏能够近一步提高小明的智商。

游戏规则如下:

现在有N条鱼,每条鱼的体积为Ai,从左到右排成一排。A数组是一个排列。

小明每轮可以执行一次大鱼吃小鱼的操作。一次大鱼吃小鱼的操作:对于每条鱼,它在每一次操作时会吃掉右边比自己小的第一条鱼。

值得注意的是,在一次操作中,每条鱼吃比自己小的鱼的时候是同时发生的。

举一个例子,假设现在有三条鱼,体积为分别[5,4,3]5443,一次操作后就剩下[5]一条鱼。

爸爸问小明,你知道要多少次操作,鱼的数量就不会变了嘛?

输入描述

第一行输入长度N

第二行输入A数组,数字之间用空格隔开

1<=N<=10^5`,`1<=Ai<=N

输出描述

一个正整数, 表示要多少次操作,鱼的数量就不会变了。

示例一

输入

3
1 2 3

输出

0

说明

无需操作A数组。

示例二

输入

6
4 3 2 3 2 1

输出

2

说明

[4,3,2,3,2,1]-->[4,3]-->[4]

解题思路

用比较严谨的数学语言来翻译该题,描述如下。

对于数组nums中所有尽可能长的严格递减子区间[a, b],每一次我们都用区间的最大值a来替换掉该区间,得到一个新的数组nums_new。对于nums_new做相同的操作,直到nums_new不再发生变化,问一共需要几次操作。

该问题显然可以用模拟的暴力方法来解决,时间复杂度为O(N^2),部分用例将无法通过。在想不到更优解法的时候,可以尝试暴力法。本篇题解主要讨论单调栈解法。

考虑如下用例5 4 4 2 2 1 3 2,会经历以下过程。

在这里插入图片描述

观察可以发现,由于位于右边的较小的鱼迟早会被位于左边的较大的鱼吃掉,假设位于左边的大鱼所经历的轮数为time_big,若干位于右边的较小的鱼所经历的轮数构成的列表为time_small_list(这些小鱼之间不会再互相吞吃,即time_small_list从左到右呈现非递减的取值)。

对于time_small_list中特定的time_smalltime_big的表达式为

time_big = max(time_big+1, time_small)

其中+1表示在之前得到time_big的基础上,吃掉小鱼还需要多花费1轮,time_small为小鱼之前经历的轮数,两者的较大值才是time_big的结果。

得到该结论之后,就很容易想到本问题可以使用逆序遍历的****单调栈来解决了:

  1. 栈中储存一个二元元组(num, time),分别为鱼的体积和该鱼所经历的轮数
  2. 逆序遍历原数组nums中的元素num,若
    1. 栈为空栈,或num小于等于栈顶元素储存鱼的体积,则该条鱼无法吃到任何一条鱼。
      • (num, 0)压入栈中
    2. num大于栈顶元素储存鱼的体积,则该大鱼可以吃掉若干栈顶的小鱼。
      • 初始化time_big = 0
      • 使用一个while循环,不断弹出栈顶小鱼,更新time_big = max(time_big+1, time_small)
      • while循环结束后,将(num, time_big)压入栈中

上述过程的核心代码为

for num in nums[::-1]:if len(stack) == 0 or stack[-1][0] >= num:stack.append((num, 0))else:time_big = 0while stack and stack[-1][0] < num:num_small, time_small = stack.pop()time_big = max(time_big+1, time_small)stack.append((num, time_big))

下面的图解展示了用单调栈解决该问题的过程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

我们发现我们的过程中在对于5 4 2 2 3的情况我们用4把后面3条鱼吃掉了,但实际上4在第2轮就会被5吃掉了。这实际上这并不影响答案的正确性,因为后面的小鱼2 2 3终究会被吃掉,不论是被4还是被5吃掉,都需要花费3轮,我们让4来做该操作,是让4代替5来吃鱼,后续的花费会在取最大值的过程中转换。

代码

Python

# 题目:【单调栈】Bilibili2021秋招-大鱼吃小鱼
# 作者:闭着眼睛学数理化
# 算法:单调栈
# 代码有看不懂的地方请直接在群上提问# 输入数组大小,数组
n = input()
nums = list(map(int, input().split()))
# 初始化空的单调栈,栈中储存(num, time)这样一个二元组
stack = list()# 逆序遍历nums中的每一个元素num
for num in nums[::-1]:# 空栈以及栈顶元素对应的鱼体积大于等于num的情况# 该分支语句其实可以不用单独列出,可以被else中的语句所包含# 但为了代码逻辑清晰,还是单独列出该分支if len(stack) == 0 or stack[-1][0] >= num:stack.append((num, 0))# 栈顶元素对应的鱼体积小于num的情况# 即num可以吃掉若干栈顶元素对应的鱼else:# 初始化该大鱼需要经历的轮数为0time_big = 0# 用一个while循环弹出若干栈顶的小鱼# 将其中所经历的轮数的最大值+1后赋值给time_bigwhile stack and stack[-1][0] < num:# 弹出栈顶小鱼,其体积和经历的轮数分别为num_small, time_smallnum_small, time_small = stack.pop()time_big = max(time_big+1, time_small)# 该大鱼吃掉若干小鱼后,要将其体积和所经历的轮数重新压回栈顶stack.append((num, time_big))# 退出循环后,栈中剩余的所有鱼所经历轮数的最大值,即为答案
print(max(time for num, time in stack))

Java

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int[] nums = new int[n];for (int i = 0; i < n; i++) {nums[i] = scanner.nextInt();}// Initialize an empty stack of pairs (num, time)Stack<Pair> stack = new Stack<>();for (int i = n - 1; i >= 0; i--) {int num = nums[i];if (stack.isEmpty() || stack.peek().num >= num) {stack.push(new Pair(num, 0));} else {int timeBig = 0;while (!stack.isEmpty() && stack.peek().num < num) {Pair pair = stack.pop();int numSmall = pair.num;int timeSmall = pair.time;timeBig = Math.max(timeBig + 1, timeSmall);}stack.push(new Pair(num, timeBig));}}int maxTime = 0;while (!stack.isEmpty()) {maxTime = Math.max(maxTime, stack.pop().time);}System.out.println(maxTime);}static class Pair {int num;int time;Pair(int num, int time) {this.num = num;this.time = time;}}
}

C++

#include <iostream>
#include <vector>
#include <stack>using namespace std;struct Pair {int num;int time;Pair(int num, int time) : num(num), time(time) {}
};int main() {int n;cin >> n;vector<int> nums(n);for (int i = 0; i < n; ++i) {cin >> nums[i];}stack<Pair> stack;for (int i = n - 1; i >= 0; --i) {int num = nums[i];if (stack.empty() || stack.top().num >= num) {stack.push(Pair(num, 0));} else {int timeBig = 0;while (!stack.empty() && stack.top().num < num) {Pair pair = stack.top();stack.pop();int numSmall = pair.num;int timeSmall = pair.time;timeBig = max(timeBig + 1, timeSmall);}stack.push(Pair(num, timeBig));}}int maxTime = 0;while (!stack.empty()) {maxTime = max(maxTime, stack.top().time);stack.pop();}cout << maxTime << endl;return 0;
}

时空复杂度

时间复杂度:O(N)。每个元素至多只需出入栈一次。

空间复杂度:O(N)。单调栈所占空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

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

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

相关文章

c语言:矩阵交换

题目&#xff1a; 代码和思路&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<stdio.h>int main() {int n 0;int m 0;int arr[10][10] { 0 }; // 输入行和列scanf("%d%d", &n, &m);int i 0;int j 0;//读取数组for (i 0; i < n; i)…

ASUS华硕ROG幻13笔记本电脑GV301QE原厂Windows10系统

链接&#xff1a;https://pan.baidu.com/s/1aPW0ctRXRNAhE75mzVPdTg?pwdds78 提取码&#xff1a;ds78 华硕玩家国度幻13笔记本电脑锐龙版Ryzen 7 5800HS,显卡3050 3050Ti,3060,3060Ti,3070,3070Ti 原厂W10系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办…

MATLAB中plotmatrix函数用法

目录 语法 说明 示例 使用两个矩阵输入创建散点图矩阵 使用一个矩阵输入创建散点图矩阵 指定标记类型和颜色 创建并修改散点图矩阵 plotmatrix函数的功能是创建散点图矩阵。 语法 plotmatrix(X,Y) plotmatrix(X) plotmatrix(___,LineSpec) plotmatrix(ax,___) [S,AX,B…

让别人访问电脑本地

查看本地IP地址&#xff1a; 使用ipconfig&#xff08;Windows&#xff09;或ifconfig&#xff08;Linux/macOS&#xff09;命令来查看你的计算机本地网络的IP地址。确保*****是你的本地IP地址。 防火墙设置&#xff1a; 确保你的防火墙允许从外部访问*****。你可能需要在防火…

服务注册发现 springcloud netflix eureka

文章目录 前言角色&#xff08;三个&#xff09; 工程说明基础运行环境工程目录说明启动顺序&#xff08;建议&#xff09;&#xff1a;运行效果注册与发现中心服务消费者&#xff1a; 代码说明服务注册中心&#xff08;Register Service&#xff09;服务提供者&#xff08;Pro…

Since Maven 3.8.1 http repositories are blocked

原因 高版本的maven不支持http的存储库。 解决方案 其实方法有好几种&#xff0c;比如降级maven版本至3.6.3(之前一直用的都是这个版本)&#xff0c;我选择了一种比较快(但不一定安全)的方式&#xff0c;因为3.6.3版本被我卸载了&#xff0c;这里直接修改idea的setting配置&…

[CUDA]去除Eigen库中的warning

一、问题提出 假如使用nvcc对cuda代码进行编译时&#xff0c;如果代码中使用了Eigen库&#xff08;头文件&#xff09;&#xff0c;编译时可能会显示很多warning information&#xff0c;如下图红框中所示&#xff1a; 这些warning信息虽然不会影响代码的实际运行&#xff0c;…

使用html2canvas转换table为图片时合并单元格rowspan失效,无边框显示问题解决(React实现)

最近使用 html2canvas导出Table表单为图片&#xff0c;但是转换出的图片被合并的单元格没有显示边框 查了原因是因为我为tr设置了背景色&#xff0c;然后td设置了rowspan&#xff0c;设置了rowspan的单元格就会出现边框不显示的问题。 解决方法就是取消tr的背景色&#xff0c;然…

图片地址GPS经纬度查询

先打开exif图片查询的网站&#xff1a; 改图宝的&#xff1a;https://www.gaitubao.com/exif图虫de的:EXIF信息查看器 (tuchong.com) 将这个地点&#xff1a;51 deg 30 51.90" N, 0 deg 5 38.73" W 修改为&#xff1a;5130 51.90" N, 05 38.73" W 到谷…

OSI参考模型

目录 一. OSI参考模型的各层功能二. 网络排错三. 网络安全四. 实体、协议、服务和服务访问点SAP五. TCP IP体系结构 一. OSI参考模型的各层功能 \quad \quad \quad \quad 我们首先来看应用层实现的功能 每个字段的各种取值所代表的意思 \quad \quad 比如要保存的文件内容是ab…

「Verilog学习笔记」用3-8译码器实现全减器

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 首先列出3-8译码器和全减器的真值表 全减器真值表如下 3-8译码器真值表如下 timescale 1ns/1nsmodule decoder_38(input E ,input A0 …

KylinOSv10修改ulimit值

问题 ulimit 值过小&#xff0c;可能导致压力测试遇到瓶颈&#xff0c;比如通过nginx建立tcp长链接时&#xff0c;链接数量受限。需要修改ulimit值&#xff0c;Linux默认为1024。 解决 使用root或sudo权限&#xff0c;编辑文件/etc/security/limits.conf&#xff0c;新增以下…

数据资产入表,给企业带来的机遇和挑战

作为推动数字经济发展的核心要素&#xff0c;近年来&#xff0c;数据资源对于企业特别是相关数据企业的价值和作用正日益凸显。 数据资产入表之后&#xff0c;能够为企业经营带来实质性的收益。“随着数据资产的纳入&#xff0c;企业的资产也出现了新标的。在资产负债表中&…

letcode::最小栈

最小栈 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。…

如何简单挖掘公益SRC?

目录 1、寻找漏洞 1)谷歌语法 2)fofa 2、挖掘漏洞 3、提交报告 第一步&#xff1a;“标题”和“厂商信息”和“所属域名” 第二步&#xff1a;其它内容 第三步&#xff1a;复现步骤 0、IP域名归属证明 1、漏洞页 2、该干啥 3、注入的结果 4、上榜吉时 时间&#x…

opencv(3):控制鼠标,创建 tackbar控件

文章目录 控制鼠标相关APIsetMouseCallbackcallback TrackBar 控件cv2.createTrackbarcv2.getTrackbarPos&#xff1a; 控制鼠标相关API setMouseCallback(winname, callback, userdata)callback(event, x, y, flags, userdata) setMouseCallback 在 OpenCV 中&#xff0c;s…

主办方:上海视频媒体,多样式多渠道跨屏传播

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 一&#xff0c;邀请视频媒体参加活动发布会&#xff0c;好处多多&#xff0c;首先现场气氛会很热烈&#xff0c;主办方会很有面子&#xff0c;视频媒体不管是电视台还是视频网站&#xf…

指针学习(五)

一.函数指针数组 定义&#xff1a;函数指针放进数组中&#xff0c;就叫函数指针数组&#xff0c;准确的说&#xff0c;将一个函数的地址存到⼀个数组中 那这个数组就叫函数指针数组。 int (*pi[5])(int); 解读&#xff1a;pi先和[]结合&#xff0c;因此是数组&#xff0c;加i…

JVM:字节码文件,类的生命周期,类加载器

JVM&#xff1a;字节码文件&#xff0c;类的生命周期&#xff0c;类加载器 为什么要学这门课程 1. 初识JVM1.1. 什么是JVM1.2. JVM的功能1.3. 常见的JVM 2. 字节码文件详解2.1. Java虚拟机的组成2.2. 字节码文件的组成2.2.1. 以正确的姿势打开文…

[内存泄漏][PyTorch](create_graph=True)

PyTorch保存计算图导致内存泄漏 1. 内存泄漏定义2. 问题发现背景3. github中pytorch源码关于这个问题的讨论 1. 内存泄漏定义 内存泄漏&#xff08;Memory Leak&#xff09;是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#…