随笔:实现一个队列,使得取出最大值的时间复杂度较低

实现一个栈,获取其中最大元素,获取时间复杂度为O(1) /**  * 实现一个栈,获取其中最大元素,获取时间复杂度为O(1)  * @MWD  * Date:2013-9-4  *  * Reference: http://www.cnblogs.com/pangxiaodong/archive/2011/08/12/2136260.html  */ package test; import java.util.*; p 阅读详情

该题是《编程之美》中的题目,最后提供的方法看起来挺好玩的,书里的代码看起来好像实现不了,做了下小调整,整成java的,测试可以实现功能。取出最大值的时间复杂度为O(1)。

这个题有几种解法,如引入最大堆,这样取出最大值的时间复杂度为O(1),入队列和出队列的时间复杂度要O(log2N)

提供一种解法:

用栈结构实现取出最大值功能比较简单,而用两个栈可以实现一个队列的功能,所以这道题就用两个具有O(1)时间复杂度取出最大值的栈构成一个队列。

java代码如下:

public class MaxNumFromStack {
	public static void main(String[] args) {
		
//		MyStack stack=new MyStack();
//		stack.push(2);
//		stack.push(3);
//		stack.push(4);
//		stack.push(5);
//		stack.push(1);
//		stack.push(10);
//		stack.push(8);
//		for(int i=0;i<6;i++){
//			System.out.println("TheNum:"+stack.pop());
//			System.out.println("MaxNum:"+stack.getMax());
//			System.out.println("=========================");
//		}
		MyQueue queue=new MyQueue();
		queue.insert(2);
		queue.insert(30);
		queue.insert(4);
		queue.insert(8);
		queue.insert(10);
		queue.insert(5);
		for(int i=0;i<4;i++){
			System.out.println("TheNum:"+queue.deQueue());
			System.out.println("MaxNum:"+queue.getMax());
			System.out.println("============================");
		}
	}
}
class MyStack{
	private int top;
	private int maxIndex;
	private int MAX;
	private int[] data;
	private int[] maxStackIndex;
	public MyStack(){
		MAX=10;
		top=-1;
		maxIndex=-1;
		data=new int[MAX];
		maxStackIndex=new int[MAX];
	}
	//入栈
	public void push(int num){
		top++;
		if(top>=MAX){
			System.out.println("栈已满,不能入栈");
			return;
		}
		data[top]=num;//先添加到栈中
		if(num>getMax()){//大于当前最大值
			maxStackIndex[top]=top;//当前是最大值
			maxIndex=top; 
		}else{
			//保留最大的值
			maxStackIndex[top]=maxIndex;
		}
	}
	//出栈
	public int pop(){
		if(top<0){
			System.out.println("栈为空,不能出栈");
			return Integer.MIN_VALUE;
		}
		int num=data[top];
		if(top==0){
			maxIndex=-1;
		}else if(top==maxIndex){//当前栈顶是最大值,调整最大值
			maxIndex=maxStackIndex[top-1];
		}
		top--;
		return num;
	}
	public int getMax(){
		if(maxIndex>=0){
			return data[maxIndex];
		}else{
			//返回最小值
			return Integer.MIN_VALUE;
		}
	}
	public boolean isEmpty(){
		return top==-1;
	}
}
class MyQueue{
	private MyStack stackA=new MyStack();
	private MyStack stackB=new MyStack();
	public void insert(int num){
		stackB.push(num);
	}
	public int deQueue(){
		if(stackA.isEmpty()){
			while(!stackB.isEmpty()){
				stackA.push(stackB.pop());
			}
		}
		return stackA.pop();
	}
	public int getMax(){
		return max(stackA.getMax(),stackB.getMax());
	}
	private int max(int a,int b){
		return a>b?a:b;
	}
}

输入:

TheNum:2
MaxNum:30
============================
TheNum:30
MaxNum:10
============================
TheNum:4
MaxNum:10
============================
TheNum:8
MaxNum:10
============================


C++面试宝典第35题:滑动窗口最大值 这道题主要考察了滑动窗口问题的求解方法,特别是如何使用双端队列来优化窗口内最大值的查找效率。通过比较暴力求解法和双端队列法,我们可以更好地理解不同算法在时间复杂度和空间复杂度上的优劣,并选择最适合问题的方法来解决。 阅读详情

相关推荐

银河麒麟系统完美安装EasyConnect

Kylin V10桌面版完美安装EasyConnect

weixin_53874797的博客 1万+

1.时间复杂度和简单排序算法

时间复杂度和简单排序算法 1.时间复杂度 如果一个算法的最差情况操作次数为O(aN^2 + bN + c),则时间复杂度为O(N^2)。只取最高项且系数为1。 如果两个算法1和算法2时间复杂度指标都一样都是O(N),但是算法1N的常数项是10,算法2的N的常数项为1,算法1不一定比算法2好,因为算法1的常数项10可能是位运算,算法2的常数项1可能是乘法运算。评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的实际运行时间,也就是“常数时间”。 2.简单排序算法 例题①选择排序:每次循环交

weixin_44897707的博客 552

均匀分布产生高斯分布

均匀分布产生高斯分布 文章目录均匀分布产生高斯分布简介方法和证明代码效果引用 简介 方法和证明 代码 效果 引用

gy_Rick的博客 5317

改良stack的push操作,使得从stack中获取最大元素的时间复杂度为O(1) [转]

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33895516的博客 295

解决VMWare ESXi PCIe直通显卡导致的DevicePowerOn启动故障

本文详细解析了VMWare ESXi中PCIe直通显卡导致的DevicePowerOn启动故障,重点分析了MMIO空间不足的根本原因,并提供了完整的解决方案。通过修改.vmx文件中的关键参数,如pciPassthru.64bitMMIOSizeGB,可以有效解决显存分配问题。文章还涵盖了硬件兼容性检查、性能调优技巧及大规模部署的实战案例,帮助用户彻底解决显卡直通难题。

weixin_42537919的博客 575

双目视觉三维重构(一)————简介

优快云中关于立三维重构的介绍层出不穷,CNKI中也有各类综述对三维重构进行总结,撰写这篇博客仅作为本人对该类博客、论文的总结学习,加深自身学习的印象、作为学习的笔记。如有错误的地方,欢迎指正。   1、三维重构 1.1、三维重构到底是什么?   首先要了解立体匹配算法,首先要知道立体匹配算法主要具体应用于什么方向。 三维重构又被称为三维重建,百度百科中对它的定义为:指对三维物体建立适合...

qq_39634612的博客 1万+

找出最大值和最小值的时间复杂度比较小的一种方法

一般认为,对于给定的n个数,只要独立地找出最小值和最大值,各用n-1次比较,最多2(n-1)次就可以找出最大值和最小值。        实际上,至多3(n/2)次比较就足以同时找到最大值和最小值,具体做法是:成对的处理元素,先将一对元素互相比较,然后将最小者与当前最小值比较,将较大者与当前最大值比较,因此每两个元素需要3次比较。这里要注意n的奇偶,当n是奇数,就将最小值和最大值都设置为第一个元素

xumesang的专栏 1万+

LLC 谐振变换器开发设计1

本文档详细介绍了基于DSP28335的LLC谐振变换器开发设计。系统采用频率调制(FM)控制方式,实现高效率、高功率密度的隔离型DC/DC变换。文档阐述了LLC拓扑结构和工作原理,给出了谐振频率、品质因数等关键参数的计算公式。硬件设计包括功率器件选型和采样电路实现,软件部分提供了DSP28335的核心控制算法和代码示例,涵盖频率转换、PI控制和PWM生成。系统还设计了启动策略和保护机制,确保可靠运行。该设计实现了主开关零电压开通和低纹波输出特性。

330

栈和队列:实现一个栈,O(1)时间复杂度获取栈内最大元素

实现一个栈,获取栈内最大元素 题目:实现一个栈,使栈的Push、Pop Top和Max的时间复杂度为O(1),Max()将返回栈内最大的元素。 思路:用两个栈,第一个是常规栈,第二个只存储到来的元素中比栈顶大的元素。 复杂度分析:时间复杂度符合题目要求O(1)。空间复杂度最坏情况附加的stack中需要储存每个元素,故额外使用O(n) 空间。 class stackWithMax{ private: stack<int> valueStack;

sessos的博客 1620

Python画柱状图(双柱状图,三柱状图)且显示对应数值

使用python实现双柱状图和三柱状图,并且在柱状图形的顶部显示对应数值;

yue200403的博客 1万+

图神经网络实战(2)——图论基础

图论 (Graph theory) 是数学的一个基本分支,涉及对图研究。图是复杂数据结构的可视化表示,有助于理解不同实体之间的关系。图论提供了大量建模和分析现实问题的工具,如交通系统、社交网络和互联网等。在本节中,将介绍图论的基本原理,主要涉及三个方面:图属性、图概念和图算法。

盼小辉丶的博客 1万+

队列的最大值

效率比较高的做法: 使用双向队列(,队列中只存放当前元素的下标,设新来的元素为k,如果前面的元素比k小,直接把前面的删除(因为不可能成为后面窗口的最大值),如果前面的元素比k大,判断是否还在窗口范围内,不在则移除 ①先判断当前队列是否为空,如果不空而且当前元素比队列中尾端的元素大,将队列元素的尾端弹出; ②判断队列头元素(存的是下标)是否还在滑动窗口范围中,不在则把头元素移除; /** ...

中都 1132

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

编程之美之队列中取最大值操作

编程之美之队列中取最大值操作 剑指offer之取栈中最小值操作

fangjian1204的专栏 2225

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

每日一题——滑动窗口最大值:单调队列的应用

每日一题——滑动窗口最大值:单调队列的应用

zxjiaya的博客 1420

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

剑指offer之65 滑动窗口的最大值问题

剑指offer65在线提交题目描述如下: 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1},

木子傑Bayes的专栏 830

dequeue维护最大值

编程之美 -  队列中取最大值操作问题 假设有这样一个拥有3个操作的队列:     1. EnQueue(v):将v加入队列中     2. DeQueue:使队列中的对首元素删除并返回此元素     3. MaxElement:返回队列中的最大(小)元素     请设计一个数据结构和算法,让MaxElement操作的时间复杂度尽可能的低。      因为在栈s1外只要多开一个s2,

joshua_jh的专栏 638

Python面试宝典第2题:滑动窗口最大值

给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。滑动窗口每次只向右移动一位,你只可以看到在滑动窗口内的k个数字,请返回滑动窗口中的最大值。

hope_wisdom的技术博客 1644

59 - II. 队列的最大值

题目 请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。 若队列为空,pop_front 和 max_value 需要返回 -1 示例 1: 输入: [“MaxQueue”,“push_back”,“push_back”,“max_value”,“pop_front”,“max_value”] [[],[1],[2],[],[],[]] 输出: [null,null,null,2,1,2]

qq_45630711的博客 152

单调队列与优先级队列详述

优先级队列(Priority Queue):是一种特殊的队列数据结构,其中的元素具有优先级。在优先级队列中,元素按照优先级的顺序进行排序,每次从队列中取出的元素都是具有最高优先级的元素。它在处理最值方面的问题优势较大。总结来说,单调队列和优先队列是两种不同的数据结构,适用于不同的场景和问题。:优先队列通常使用堆(二叉堆或斐波那契堆)来实现,这使得插入和删除操作的时间复杂度为O(log n),其中n是队列中元素的数量。通常,单调队列维护一个递增或递减的顺序,以便在常数时间内获取队列中的最大或最小元素。

weixin_61500998的博客 2444

LeetCode 239 滑动窗口最大值

滑动窗口最大值问题是一个经典的算法问题,通过使用双端队列可以高效地解决。这种方法不仅提高了算法的效率,还展示了数据结构在优化算法中的重要性。希望这篇文章能帮助你更好地理解和应用滑动窗口技术。在实际应用中,选择合适的算法和数据结构至关重要。对于滑动窗口问题,双端队列提供了一种高效且优雅的解决方案。通过维护一个单调递减的队列,我们可以在 O(n) 的时间复杂度内完成计算,这对于处理大规模数据尤为重要。

qq_64604732的博客 1181

编程之美3.7——队列中取最大值操作问题

推荐http://blog.youkuaiyun.com/linyunzju/article/details/7765324 http://www.cnblogs.com/kurtwang/archive/2010/09/22/1833132.html 问题: 假设有这样一个拥有3个操作的队列: 1. EnQueue(v): 将v加入队列中 2. DeQueue(): 使队列

hwltony的专栏 723

代码随想录二刷-滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。b. 因为本题要保证单调递减,所以如果队列里是5 1,现在有4入队的话,需要把1剔除掉,最后队列剩5 4,保证单调递减。c. 首先,模拟一下滑动窗口,滑动窗口本质上就是每次最前面的元素会弹出,后一个元素会进来,这符合队列里的。,每次移动窗口的时候去和下一个入队的元素比较。窗口里的最大值位置是未知的,所以每次滑动窗口时,不知道。a. 先定义一个单调队列的类【队列基本功能实现:push(),pop(),front()】

Bryant_cqc的博客 1321

NC82--滑动窗口的最大值

一、题目描述 原题链接:点这里 题目大意:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值,窗口大于数组长度的时候,返回空。 二、算法一:暴力 算法思路 如果num数组为空,或者num数组长度小于窗口长度,或者窗口长度非正,这些情况都没有区间最大值,则直接返回一个空的vector 当然,你可以直接写vector<int>(),但是常数很大,很耗费时间,所以我们在代码前面定义一个ans,此时直接返回 遍历num数组,依次计算以i为左端的窗口的最大值,边界条件是窗口右端<num.

Gh0st_Lx的博客 319

int maxNum = INT_MIN; // 初始化当前窗口的最大值为最小整数 这个代码没理解/滑动窗口最大值

暴力枚举滑动窗口最大值是一个经典的算法问题,它要求找出数组中所有指定大小的滑动窗口中的最大值。下面我为你提供几种C++解决方案,从直观但低效的暴力法到高效的双端队列法。

weixin_55617272的博客 1037

深入探讨优先队列:原理、实现与应用

深入探讨优先队列:原理、实现与应用

祯的博客 1138
上一篇: 随笔:设计一个栈结构,使得取出栈中最大值时间复杂度为O(1)
下一篇: 算法笔记-链表
KeepThinking_
博客等级 码龄15年 50粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值