给定一个不含有重复值的数组 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]}
解题思路:
这个题目利用单调栈结构可以使时间复杂度降低到O(N)。首先题目是没有重复值的数组,注意,如果是有重复值的数组稍有区别。
1、先准备一个栈,用来存放所给数组元素的位置;
2、如果找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i]小的位置,那么需要让 stack 从栈顶到栈底的位置所代表的值是严格递减的;如果找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i]大的位置,那么需要让 stack 从栈顶到栈底的位置所代表的值是严格递增的,本题目采用前者;
3、循环遍历数组压入栈中,压栈和出栈方式:
- 当前栈为空,压入arr[0] = 3;
- 压入arr[1] = 4时,因为4 > 3,满足从栈顶到栈底单调减原则,所以压入;
- 压入arr[2] = 1时,因为1 < 4 , 违反了从栈顶到栈底单调减原则,所以弹出arr[1] = 4,此时,弹出位置的下面位置就是距离它左边最近的比它小的值,即为3,距离它右边最近比它小的值就是当前要压入的值,即为1,;
- 压入arr[3] = 5,因为5 > 1,满足从栈顶到栈底单调减原则,所以压入;
- 压入arr[4] = 6,因为6 > 5,满足从栈顶到栈底单调减原则,所以压入;
- 压入arr[5] =2,因为2 < 6,违反了从栈顶到栈底单调减原则,所以依次弹出arr[4] = 6,arr[3] = 5,得到arr[4] = 6左右距离最近且小于它的值的位置[3,5]和arr[3] = 5左右距离最近且小于它的值的位置[2,5];
- 压入arr[6] = 7,因为7 > 2,满足从栈顶到栈底单调减原则,所以压入;
至此,所有元素已经全