题目:给定一个不含重复值的数组,找到每一个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}}
进阶问题:给定一个可能含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置。返回所有位置相应信息
要求:如果arr长度为N,实现原问题和进阶问题的解法,时间复杂度都达到O(N)
思路:准备一个栈,标记为stack, 栈中放的元素是数组的位置,开始时stack为空。
如果找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,那么需要让stack从栈顶到栈底的位置所代表的值是严格递减的;
如果找到每一个位置左边和右边离i位置最近且值比arr[i]大的位置,那么需要让stack从栈顶到栈底的位置所代表的值是严格递增的
def getNearNorepeat(L):
res = [[0,0]]*len(L)
stack = []
for i in range(len(L)):
while len(stack)!=0 and L[stack[-1]] > L[i]:
popIndex = stack.pop()
if len(stack) == 0:
lessLeftIndex = -1
else:
lessLeftIndex = i
res[popIndex][0] = lessLeftIndex
res[popIndex][1] = i
stack.push(i)
while len(stack)!=0:
popIndex = stack.pop()
if len(stack) == 0:
lessLeftIndex = -1
else:
lessLeftIndex = stack[-1]
res[popIndex][0] = lessLeftIndex
res[popIndex][1] = -1
return res
def getNearLess(L):
res = [[0,0]] * len(L)
stack = []
for i in range(len(L)):
while len(stack)!=0 and L[stack[-1][0]] > L[i]:
popIndex = stack.pop()
if len(stack)==0:
leftLessIndex = -1
else:
leftLessIndex = stack[-1][len(stack[-1])-1]
for index in popIndex:
res[index][0] = leftLessIndex
res[index][1] = i
if len(stack)!=0 and L[stack[-1][0]] == L[i]:
stack[-1].append(i)
else:
list_ = []
list_.append(i)
stack.push(list_)
while len(stack)!=0:
popIndex = stack.pop()
if len(stack) == 0:
leftLessIndex = -1
else:
leftLessIndex = stack[-1][len(stack[-1])-1]
for index in popIndex:
res[index][0] = leftLessIndex
res[index][1] = -1
return res
整个过程中,进栈一次,出栈一次,所以整个流程时间复杂度为O(N)