单调栈

Apr 25, 2024
2 views
Algorithm

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

1. 题目描述

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

输入描述: 第一行输入一个数字 n,表示数组 arr 的长度。 以下一行输入 n 个数字,表示数组的值

输出描述: 输出n行,每行两个数字 L 和 R,如果不存在,则值为 -1,下标从 0 开始。

示例1

输入 7 3 4 1 5 6 2 7

输出 -1 2 0 2 -1 -1 2 5 3 5 2 -1 5 -1

2.解题思路

维护一个从小到大值递增的栈,但是栈中存放的是索引。

遍历数组的每一个元素,

如果当前元素比栈顶(索引对应的数值)小,那么弹出栈顶元素(索引)index,如果此时栈不为空,这个index的离index左侧最近且比它小的元素是新的栈顶,离右侧最近且比它小的元素是当前元素的索引;如果栈为空,这个index的离index左侧最近且比它小的元素是-1,离右侧最近且比它小的元素是当前元素的索引

如果栈为空或者当前元素比栈顶(索引对应的数值)大,那么直接压栈即可。

遍历完所有元素后,如果此时栈不为空,则依次弹出每一个元素(索引)index,如果此时栈不为空,这个index的离index左侧最近且比它小的元素是新的栈顶,离右侧最近且比它小的元素是-1。如果栈为空,这个index的离index左侧最近且比它小的元素是-1,离右侧最近且比它小的元素是-1。

3.代码实现

n=int(input())
arr = list(map(int,input().split()))
res=[[0 for _ in range(2)] for _ in range(n)]
stack=[]
for i in range(n):
    while len(stack)>0 and arr[stack[-1]]>arr[i]:
        index=stack.pop(-1)
        if len(stack)>0:
            res[index][0]=stack[-1]
        else:
            res[index][0]=-1

        res[index][1]=i
    stack.append(i)
while len(stack)>0:
    index=stack.pop(-1)
    if len(stack)>0:
        res[index][0]=stack[-1]
    else:
        res[index][0]=-1
    res[index][1] = -1
for i in range(n):
    print (str(res[i][0])+" "+str(res[i][1]))