ここでは、数値が格納された配列において、各要素から見て、前に出現する最初の次に大きい値(表現が難しいですが、直近の最小値?)を見つけるプログラムを python3 で実装してみます。
# Monotonic Stack
# 配列 nums の各要素において、
# その要素よりも左側に出現する、
# その要素の次に大きい値を格納する配列を作成します。
nums = [1,4,3,7,4,5]
n = len(nums)
inf = float('INF')
leftVal = [inf * -1] * n #各要素よりも左側にある、次に大きい値を格納する配列
leftBoundary = [inf * -1] * n # ↑ の index を格納する配列
leftStack = []
#右側から探索
for i in range(n-1, -1, -1):
# 現在探索している値が、スタック(leftStack)内の値よりも小さい場合は、
# その小さい値で配列を更新します
while leftStack and nums[leftStack[-1]] > nums[i]:
leftBoundary[leftStack[-1]] = i
leftVal[leftStack[-1]] = nums[i]
leftStack.pop()
leftStack.append(i)
print(leftBoundary) # --> [-inf, 0, 0, 2, 2, 4] # -inf は存在しないという意味です。
print(leftVal) # --> [-inf, 1, 1, 3, 3, 4]
逆に、ある要素よりも右側にある直近の最小値を探索するには、以下のように for ループを右向きにすれば良いですね。
nums = [1,4,3,7,4,5]
n = len(nums)
inf = float('INF')
rightVal = [inf * -1] * n #各要素よりも左側にある、次に大きい値を格納する配列
rightBoundary = [inf * -1] * n # ↑ の index を格納する配列
rightStack = []
#左側から探索
for i in range(n):
# 現在探索している値が、スタック(rightStack)内の値よりも小さい場合は、
# その小さい値で配列を更新します
while rightStack and nums[rightStack[-1]] > nums[i]:
rightBoundary[rightStack[-1]] = i
rightVal[rightStack[-1]] = nums[i]
rightStack.pop()
rightStack.append(i)
print(rightBoundary) # --> [-inf, 0, 0, 2, 2, 4] # -inf は存在しないという意味です。
print(rightVal) # --> [-inf, 1, 1, 3, 3, 4]
お役に立てれば幸いです!