栈与队列7——单调栈结构(初阶问题)

本文介绍了一种高效算法,用于在一个不重复的数组中,找出每个元素左侧和右侧最近且值较小的元素位置。通过使用单调栈数据结构,实现了O(N)的时间复杂度。

题目

一个不含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息。

举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{{-1,2},{0,2},{-1,-1},{2,5},{3,5},{2,-1},{5,-1}},其中-1表示不存在


要求

如果arr长度为N,时间复杂度达到O(N)。


思路

数据结构:单调栈,存放数组元素的索引

使用一个栈,并且使该栈从栈顶到栈底的值是严格递减的(因为找的是左右两边比当前位置小的值)。

流程:

  1. 遍历数组
  2. 栈为空或者当前arr[i]大于栈顶元素直接入栈
  3. 若栈不为空,并且当前arr[i]小于栈顶元素 j(假设为j,因为栈里存放的是数组索引值,这里比较的是arr[i]<arr[j]),则需要弹出栈顶元素,则对于弹出的元素j来说左边位置离j最近并且小于arr[j]的值为当前栈顶对应的值,右边位置则是i;
  4. 遍历完数组后,若栈不为空,则对于栈中的所有元素,它们的右边位置最近并且小于他们的值都不存在即为-1;依次弹出栈顶元素 j (假设为j),j的右边为-1,左边位置为当前栈顶元素;完成!

源码

public int[][] getNearLessNoRepeat(int[] arr){
	//返回的二维数组,代表左右的位置
	int[][] res=new int[arr.length][2];
	//栈
	Stack<Integer> stack=new Stack<Integer>();
	//遍历数组
	for(int i=0;i<arr.length;i++){
		//栈不为空,并且当前数组元素小于栈顶元素
		while(!stack.isEmpty()&&arr[stack.peek()]>arr[i]){
			int popIndex=stack.pop();
			int leftlessIndex=stack.isEmpty()?-1:stack.peek();
			int rightlessIndex=i;
			//针对于弹出的栈顶元素的左右最小的值的位置
			res[popIndex][0]=leftlessIndex;
			res[popIndex][1]=rightlessIndex;
		}
		stack.push(i);
	}
	while(!stack.isEmpty()){
		int popIndex=stack.pop();
		int leftlessIndex=stack.isEmpty()?-1:stack.peek();
		int rightlessIndex=-1;
		res[popIndex][0]=leftlessIndex;
		res[popIndex][1]=rightlessIndex;
	}
	return res;
}

如果有不理解的,欢迎随时留言交流。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值