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

题目

一个不含有重复值的数组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;
}

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

发布了43 篇原创文章 · 获赞 21 · 访问量 4930

猜你喜欢

转载自blog.csdn.net/flying_1314/article/details/103766174