单调栈就是单调递增或者单调递减的栈,也就是栈底到栈顶递增或递减,根据单调栈的的这种结构,可以很容易想到运用单调栈可以很容易的把O(n²)的时间复杂度优化到O(n),如果使用数组的话,相对的空间复杂度也不会太高
示例给定一个长度为 N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。
输入格式
第一行包含整数 N,表示数列长度。
第二行包含 N 个整数,表示整数数列。
输出格式
共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 −1。
数据范围
1≤N≤1e5 1≤数列中元素≤1e9
输入样例:
5
3 4 2 7 5
输出样例:
-1 3 -1 2 2
思路
首先思考的是暴力做法,定义一个栈,然后每次从栈顶开始寻找比当前元素小的数,找到了就直接输出,没找到输出-1,最后把当前元素入栈。暴力的做法时间复杂度是O(n²),题目N的范围可是1e5,O(n²)的时间复杂度很明显会超时,所以我们思考有没有可以优化的地方。
我们看一下有没有什么性质,看一下这个栈里面是不是有一些元素是不是永远不会作为答案输出出来。举个栗子,比如我们求下标为8的数的左边第一个比它小的数,我们这里用数组模拟栈,定义一个栈a,下标为8的数之前的数已经全部入栈了,我们假设a3>=a5,那么a3是不是永远不会作为答案输出出来,为什么a3不会永远作为答案输出呢?因为a5在a3的前面,当我们遍历栈的时候从栈顶开始遍历,肯定第一个遍历到是a5而不是a3,又因为a3>=a5,所以a3会永远不会作为答案输出.
所以我们可以发现,如果栈里面存在这样一个关系ax>=ay且x>n; for(int i=0;i>x; //如果x比栈顶元素小,删除栈顶元素,遍历栈直到找到比x小的数为止 while(t&&s[t]>=x) t--; if(t) cout
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?