单调栈结构
題目:給定一個不含重復值的數組,找到每一個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 = -1else:lessLeftIndex = ires[popIndex][0] = lessLeftIndexres[popIndex][1] = istack.push(i)while len(stack)!=0:popIndex = stack.pop()if len(stack) == 0:lessLeftIndex = -1else:lessLeftIndex = stack[-1]res[popIndex][0] = lessLeftIndexres[popIndex][1] = -1return 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 = -1else:leftLessIndex = stack[-1][len(stack[-1])-1]for index in popIndex:res[index][0] = leftLessIndexres[index][1] = iif 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 = -1else:leftLessIndex = stack[-1][len(stack[-1])-1]for index in popIndex:res[index][0] = leftLessIndexres[index][1] = -1return res整個過程中,進棧一次,出棧一次,所以整個流程時間復雜度為O(N)
總結
- 上一篇: 子数组的最大累加和问题
- 下一篇: 求最大子矩阵的大小