剑指Offer(数据结构与算法面试题精讲)C++版——day12

news2025/4/17 21:22:51

剑指Offer(数据结构与算法面试题精讲)C++版——day12

      • 题目一:小行星碰撞
      • 题目二:每日温度
      • 题目三:直方图最大矩形面积
      • 附录:源码gitee仓库

题目一:小行星碰撞

    题目:输入一个表示小行星的数组,数组中每个数字的绝对值表示小行星的大小,数字的正负号表示小行星运动的方向,正号表示向右飞行,负号表示向左飞行。如果两颗小行星相撞,那么体积较小的小行星将会爆炸最终消失,体积较大的小行星不受影响。如果相撞的两颗小行星大小相同,那么它们都会爆炸消失。飞行方向相同的小行星永远不会相撞。求最终剩下的小行星。例如,有6颗小行星[4, 5, -6, 4, 8, -5],如图6.2所示(箭头表示飞行的方向),它们相撞之后最终剩下3颗小行星[-6, 4, 8]。
在这里插入图片描述
    由题意可知,这里我们可使用栈来实现,依次检查每个小行星的运动方向以及小行星大小,比如,这里拿[+4,+5,-6]三颗行星举例,由于-6的小行星比+4和+5行星大,那么由于-6行星和+4、+5两个行星一定会相撞,最后只剩下-6行星。如果使用栈结构来存储就能够很好的解决这个问题,一开始+4直接压入到栈中,然后遇到了+5由于不存在反向,于是同样压入栈中,遇到-6(待入栈元素)之后,由于与栈顶元素方向不一致,弹出栈顶元素,比较,发现栈顶元素应该被销毁,于是接着弹出直到这个待入栈元素要么消失,要么入栈,或者栈为空。通过这样的分析可以得到如下代码:

int getDirection(int number) {
	return number > 0 ? 1 : -1;
}
vector<int> getRemain(vector<int> arr) {
	stack<int> st;
	int top=0;
	for(int i=0,size=arr.size(); i<size; ++i) {
		if(st.empty()) {
			st.push(arr[i]);
			continue;
		} else {
			top=st.top();
			if(getDirection(top)==1&&getDirection(arr[i])==-1) {
				if(abs(top)>abs(arr[i])) {
					continue;
				} else if(arr[i]==top) {
					st.pop();
				} else {
					while(!st.empty()&&abs(top)<abs(arr[i])) {
						st.pop();
						if(st.empty()) {
							break;
						} else {
							top=st.top();
						}
					}
					if(st.empty()) {
						st.push(arr[i]);
					} else if(top==arr[i]) {
						st.pop();
					}
				}
			} else {
				st.push(arr[i]);
			}
		}
	}
	vector<int> result= {};
	while(!st.empty()) {
		result.push_back(st.top());
		st.pop();
	}
	return result;
}

在这里插入图片描述

题目二:每日温度

    题目:输入一个数组,它的每个数字是某天的温度。请计算每天需要等几天才会出现更高的温度。例如,如果输入数组[35, 31, 33, 36, 34],那么输出为[3, 1, 1, 0, 0]。由于第1天的温度是35℃,要等3天才会出现更高的温度36℃,因此对应的输出为3。第4天的温度是36℃,后面没有更高的温度,它对应的输出是0。其他的以此类推。

    这里存在一个关键问题,对于前面出现过的数据,无法知道后面还有几个数,无法判断距离更大气温的天数,比如[4,3,2,1,6],只有等到所有的数都获取之后才知道最终确认距离更高气温的天数。如果是使用暴力法,那么对于第i个数,最坏情况下需要遍历其后的(n-i)个数,这样最坏的时间复杂度为O(n^2)。
    分析可以发现,对于示例数组[35,31,33,36,34],可以利用栈结构保存暂时没有确认距离更大的元素的下标,比如这里从左到右遍历,最开始遍历[35,31]都没有出现过更高气温,所以压入到栈中[0,1],接下来遍历到新元素[33],可以从栈取出栈顶元素判断,发现找到了一个更大的,用当前新来的元素的下标减去栈中元素的下标即可得到距离更大元素的下标。按照这样的方式就能够一次遍历拿到所有元素距离更大元素的个数了,最终得到代码如下:

vector<int> getRemainDays(vector<int> arr) {
	stack<int> st;
	int size=arr.size(),top=0;
	vector<int> result(size,0);
	for(int i=0; i<size; ++i) {
		if(st.empty()||arr[st.top()]>=arr[i]) {
			st.push(i);
		} else {
			top=st.top();
			while(arr[top]<arr[i]) {
				result[top]=i-top;
				st.pop();
				if(st.empty()) {
					break;
				} else {
					top=st.top();
				}
			}
		}
	}
	return result;
}

在这里插入图片描述

    这题得思路比较巧妙,很值得积累。利用了栈去保留前面没有被计算出结果,然后再利用栈得特性在之后得运算中弹出栈中元素,利用已知数据推理出结果。这里得时间复杂度为O(n),因为在最坏情况下每个元素入栈一次,出栈一次。

题目三:直方图最大矩形面积

    题目:直方图是由排列在同一基线上的相邻柱子组成的图形。输入一个由非负数组成的数组,数组中的数字是直方图中柱子的高。求直方图中最大矩形面积。假设直方图中柱子的宽都为1。例如,输入数组[3, 2, 5, 4, 6, 1, 4, 2],其对应的直方图如图6.3所示,该直方图中最大矩形面积为12,如阴影部分所示。
在这里插入图片描述
    这道题似曾相识,应该也是leetcode上面的题目。这题如果先不考虑使用栈相关的数据结构,使用前面提到的双指针法是否可行呢,设置前后指针,一开始让前后两指针都指向第一个数,然后第一个数后移,移到一定程度之后前指针也后移。分析发现这个方法是不行的,因为前一个指针往前移的过程中可能矩形会缩小,不满足双指针适用条件。
    这样不行那蛮力法呢,显然是可行的,双重遍历数组进行组合定界,比如锁定一组下标[min,max],然后矩形的面积就等于(max-min)*min{arr[min-max]},但是这样的事件复杂度太高了。
    其实,这里有一个更加巧妙的方法——单调栈法。分析发现,对于每个矩形面积的计算,可以以当前扫描到的柱子作为基准,然后向该柱子左右两次查找比基准柱子矮的柱子,比如以下标为3的坐标为例(也就是数组中第一次出现的4),扫描两侧可以发现左侧更矮的柱子下标为1(也就是数组中第一次数显的2),右侧更矮的柱子下标为5(也就是数组中的1),从而可以得到以数值4为基准的最大矩形面积为4*(5-1-1)=12。
    受到这一点的启发,我们可以得到一个非常巧妙的方法,现在的关键就在于为每个矩形左右两侧更矮的柱子定界,和前面题目2的方法类似,我们从左到右遍历数组(也就是这里矩形柱),构建一个柱子高度严格递增的矩形柱栈(为了方便获取柱子的高度和计算矩形宽度,这里和题目2一致存储下标),如果当前遍历的柱子比栈顶已有的柱子矮,那么说明当前栈顶柱子的左右下界都找到了,那么可以根据定界计算其最大矩形面积。如果当前遍历的柱子的高度比当前栈顶的柱子的高度高,那么直接入栈(以存储下标的形式)。最终得到如下代码:

int getMaxRectSquare(vector<int> arr) {
	stack<int> st;
	int result=0,size=arr.size(),top=0,height=0,width=0;
	for(int i=0; i<size; ++i) {
		while(!st.empty()&&arr[st.top()]>=arr[i]) {//构建一个严格递增的单调栈 
			height=arr[st.top()];
			st.pop();
			width=st.empty() ? i:(i-st.top()-1);
			if(width*height>result) {
				result=width*height;
			}
		}
		st.push(i);
	}
	while(!st.empty()) {
		top=st.top();
		height=arr[top];
		st.pop();
		width=st.empty()?arr.size():(arr.size()-st.top()-1);//左侧元素边界,否则取所有 
		if(width*height>result) {
			result=width*height;
		}
	}
	return result;
}

在这里插入图片描述

附录:源码gitee仓库

    考虑到有些算法需要模拟数据,如果全部放进来代码显得过长,不利于聚焦在算法的核心思路上。于是把所有的代码整理到了开源仓库上,如果想要看详细模拟数据,可在开源仓库自取:【凌空暗羽/剑指offer-C++版手写代码】。

    我是【Jerry说前后端】,本系列精心挑选的算法题目全部基于经典的《剑指 Offer(数据结构与算法面试题精讲)》。在如今竞争激烈的技术求职环境下,算法能力已成为前端开发岗位笔试考核的关键要点。通过深入钻研这一系列算法题,大家能够系统地积累算法知识和解题经验。每一道题目的分析与解答过程,都像是一把钥匙,为大家打开一扇通往高效编程思维的大门,帮助大家逐步提升自己在数据结构运用、算法设计与优化等方面的能力。
    无论是即将踏入职场的应届毕业生,还是想要进一步提升自己技术水平的在职开发者,掌握扎实的算法知识都是提升竞争力的有力武器。希望大家能跟随我的步伐,在这个系列中不断学习、不断进步,为即将到来的前端笔试做好充分准备,顺利拿下心仪的工作机会!快来订阅吧,让我们一起开启这段算法学习之旅!

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

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

相关文章

Docker学习笔记-docker安装、删除

一、在centOS 7中docker的默认安装目录 # Docker 主配置文件目录 ls /etc/docker# Docker 数据目录&#xff08;镜像、容器、卷等&#xff09; ls /var/lib/docker# Docker 可执行文件路径 which docker # 输出类似 /usr/bin/docker 二、docker文件目录说明 目录/文件用途/…

【Python 开源】你的 Windows 关机助手——PyQt5 版定时关机工具

&#x1f5a5;️ 你的 Windows 关机助手——PyQt5 版定时关机工具 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例&#xff0c;秉着开源精神的…

【Python爬虫】简单介绍

目录 一、基本概念 1.1 什么是爬虫 1.2 Python为什么适合爬虫 1.3 Python爬虫应用领域 &#xff08;1&#xff09;数据采集与分析 市场调研 学术研究 &#xff08;2&#xff09;内容聚合与推荐 新闻聚合 视频内容聚合 &#xff08;3&#xff09;金融领域 股票数据获…

使用MCP服务通过自然语言操作数据库(vscode+cline版本)

使用MCP服务操纵数据库(vscodecline版本) 本文主要介绍&#xff0c;在vscode中使用cline插件调用deepseek模型&#xff0c;通过MCP服务器 使用自然语言去操作指定数据库。本文使用的是以己经创建号的珠海航展数据库。 理解MCP服务&#xff1a; MCP&#xff08;Model Context…

Vue 3 + TypeScript 实现一个多语言国际化组件(支持语言切换与内容加载)

文章目录 一、项目背景与功能概览二、项目技术架构与依赖安装2.1 技术栈2.2 安装依赖 三、国际化组件实现3.1 创建 i18n 实例3.2 配置 i18n 到 Vue 应用3.3 在组件中使用国际化内容3.4 支持语言切换 四、支持类型安全4.1 添加类型支持4.2 自动加载语言文件 一、项目背景与功能概…

PhalApi 2.x:让PHP接口开发从“简单”到“极简”的开源框架

—— 专为高效开发而生&#xff0c;助你轻松构建高可用API接口 一、为什么选择PhalApi 2.x&#xff1f; 1.轻量高效&#xff0c;性能卓越 PhalApi 2.x 是一款专为接口开发设计的轻量级PHP框架&#xff0c;其核心代码精简但功能强大。根据开发者实测&#xff0c;在2核2G服务器…

Java 企业级应用:SOA 与微服务的对比与选择

企业级应用开发中&#xff0c;架构设计是决定系统可扩展性、可维护性和性能的关键因素。SOA&#xff08;面向服务的架构&#xff09;和微服务架构是两种主流的架构模式&#xff0c;它们各自有着独特的和设计理念适用场景。本文将深入探讨 SOA 和微服务架构的对比&#xff0c;并…

Zookeeper的典型应用场景?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper的典型应用场景?】面试题。希望对大家有帮助&#xff1b; Zookeeper的典型应用场景? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 是一个开源的分布式协调服务&#xff0c;主要用于管理和协调大…

数据分析不只是跑个SQL!

数据分析不只是跑个SQL&#xff01; 数据分析五大闭环&#xff0c;你做到哪一步了&#xff1f;闭环一&#xff1a;认识现状闭环二&#xff1a;原因分析闭环三&#xff1a;优化表现闭环四&#xff1a;预测走势闭环五&#xff1a;主动解读数据 数据思维&#xff1a;WHY-WHAT-HOW模…

Dify智能体平台源码二次开发笔记(4) - 多租户的SAAS版实现

前言 Dify 的多租户功能是其商业版的标准功能&#xff0c;我们应当尊重其盈利模式。只有保持良性的商业运作&#xff0c;Dify 才能持续发展&#xff0c;并为用户提供更优质的功能。因此&#xff0c;此功能仅限学习使用。 我们的需求是&#xff1a;实现类似 SaaS 版的账号隔离&a…

layui中transfer两个table展示不同的数据列

在项目的任务开发中需要达到transfer右侧table需要有下拉框可选择状态&#xff0c;左侧table不变 使用的layui版本为2.4.5&#xff0c;该版本没有对transfer可自定义数据列的配置&#xff0c;所以改动transfer.js中的源码 以下为transfer.js部分源码 也是transfer.js去render的…

【机器学习】机器学习笔记

1 机器学习定义 计算机程序从经验E中学习&#xff0c;解决某一任务T&#xff0c;进行某一性能P&#xff0c;通过P测定在T上的表现因经验E而提高。 eg&#xff1a;跳棋程序 E&#xff1a; 程序自身下的上万盘棋局 T&#xff1a; 下跳棋 P&#xff1a; 与新对手下跳棋时赢的概率…

STM32 BOOT设置,bootloader,死锁使用方法

目录 BOOT0 BOOT1的配置含义 bootloader使用方法 芯片死锁解决方法开发调试过程中&#xff0c;由于某种原因导致内部Flash锁死&#xff0c;无法连接SWD以及JTAG调试&#xff0c;无法读到设备&#xff0c;可以通过修改BOOT模式重新刷写代码。修改为BOOT01&#xff0c;BOOT10…

【Redis】string类型

目录 1、介绍2、底层实现【1】SDS【2】int编码【3】embstr编码【4】raw编码【5】embstr和raw的区别 3、常用指令【1】字符串基本操作&#xff1a;【2】批量操作【3】计数器【4】过期时间【5】不存在就插入 4、使用场景 1、介绍 string是redis中最简单的键值对形式&#xff0c;…

PostgreSQL全平台安装指南:从入门到生产环境部署

一、PostgreSQL核心特性全景解析 1.1 技术架构深度剖析 graph TDA[客户端] --> B(连接池)B --> C{查询解析器}C --> D[优化器]D --> E[执行引擎]E --> F[存储引擎]F --> G[物理存储]G --> H[WAL日志]H --> I[备份恢复] 1.2 特性优势对比矩阵 特性维度…

UE5 物理模拟 与 触发检测

文章目录 碰撞条件开启模拟关闭模拟 多层级的MeshUE的BUG 触发触发条件 碰撞 条件 1必须有网格体组件 2网格体组件必须有网格&#xff0c;没有网格虽然可以开启物理模拟&#xff0c;但是不会有任何效果 注意开启的模拟的网格体组件会计算自己和所有子网格的mesh范围 3只有网格…

做仪器UI用到的颜色工具网站

https://color.adobe.com/zh/create/color-wheel 1. 图片取颜色工具 2. 对比度工具&#xff0c;煤矿井下设备&#xff0c;光线暗&#xff0c;要求背景与文字有合适的对比度&#xff0c;可以用这个软件 3. 颜色生成ARGB的值工具&#xff0c;这三个工具&#xff0c;都在上面这…

网络安全·第三天·ICMP协议安全分析

一、ICMP功能介绍 ICMP&#xff08;Internet Control Message Protocal&#xff09;是一种差错和控制报文协议&#xff0c;不仅用于传输差错报文&#xff0c; 还传输控制报文&#xff0c;但是ICMP只是尽可能交付&#xff0c;提供的服务是无连接、不可靠的&#xff0c;并不能保…

SpringBoot对接火山引擎大模型api实现图片识别与分析

文章目录 一、前言二、创建应用三、后端1.SDK集成2.调用Rest API 四、前端 一、前言 Spring AI实战初体验——实现可切换模型AI聊天助手-CSDN博客 如上&#xff0c;在上一篇博客&#xff0c;我们已经实现了spring ai对接本地大模型实现了聊天机器人&#xff0c;但是目前有个新…

单片机方案开发 代写程序/烧录芯片 九齐/应广等 电动玩具 小家电 语音开发

在电子产品设计中&#xff0c;单片机&#xff08;MCU&#xff09;无疑是最重要的组成部分之一。无论是消费电子、智能家居、工业控制&#xff0c;还是可穿戴设备&#xff0c;小家电等&#xff0c;单片机的应用无处不在。 单片机&#xff0c;简而言之&#xff0c;就是将计算机…