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]))
4.进阶
给定一个可能含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。
解题思路:
维护一个从小到大值递增的栈,但是栈中存放的是索引组成的列表。
遍历数组的每一个元素,
如果当前元素比栈顶(此时栈顶是由索引组成的列表,任意取一个索引,通常取0,对应的数值)小,那么弹出栈顶元素(由所有索引组成的列表)index_list,如果此时栈不为空,这个index_list 的每个index的离index左侧最近且比它小的元素是新的栈顶的列表中的最晚加入的索引,离右侧最近且比它小的元素是当前元素的索引;如果栈为空,这个index_list 的每个index的离index左侧最近且比它小的元素是-1,离右侧最近且比它小的元素是当前元素的索引
如果当前栈不为空且当前元素与栈顶列表中的第0个索引对应的值相等,则在栈顶的列表中压入这个元素的索引。(当有重复元素出现时,一定是要加入到栈顶的)
否则栈为空或者当前元素比栈顶列表索引对应的元素大,为当前这个元素的索引创建一个新的列表,并压入栈中。
遍历完所有元素后,如果此时栈不为空,则依次弹出每一个列表index_list,如果此时栈不为空,这个index_list 的每个index的离index左侧最近且比它小的元素是新的栈顶的列表中的最晚加入的索引,离右侧最近且比它小的元素是-1;如果栈为空,这个index_list 的每个index的离index左侧最近且比它小的元素是-1,离右侧最近且比它小的元素是-1
代码实现:
n=int(raw_input())
arr = list(map(int,raw_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][0]]>arr[i]:
index_list=stack.pop(-1)
for index in index_list:
if len(stack)>0:
res[index][0]=stack[-1][-1]
else:
res[index][0]=-1
res[index][1]=i
if len(stack)>0 and arr[stack[-1][0]]==arr[i]:
stack[-1].append(i)
else:
stack.append([i])
while len(stack)>0:
index_list=stack.pop(-1)
for index in index_list:
if len(stack)>0:
res[index][0]=stack[-1][-1]
else:
res[index][0]=-1
res[index][1] = -1
for i in range(n):
print (str(res[i][0])+" "+str(res[i][1]))
ps:有空为大家画图演示
应用:leetcode739.每日温度「单调栈」