LeetCode 503:下一个更大的元素|| (单调栈 or 线段树)
作者:互联网
解题思路:
1、单调栈:因为是循环数组,因此把数组复制三遍,ans 数组复制为2倍长,维护一个单调非递增的栈,栈保存的元素是元组(a[i] , i ),如果后面的值有比栈顶元素的值大,栈顶元素出栈,更新ans[i]的值为让其出栈的值,最后返回ans数组的一半,即最终答案。
2、线段树:数组复制两遍,构建线段树,存的值是当前区间的最大值,当查询 a[i]后面是否有更大的元素时,查询线段树[i+1,i+length]的区间,如果区间最大值比a[i]大,优先访问左子树,如果左子树没有,说明一定在右子树,递归右子树;如果左子树有,递归左子树。
代码:
1 #单调栈 2 class Solution: 3 def nextGreaterElements(self, nums): 4 a = nums[:]+nums[:]+nums[:] 5 ans = [-1]*len(nums)*2 6 stack = [] 7 length = len(nums) 8 for i in range(2*length): 9 while len(stack) > 0: 10 top = stack.pop() 11 stack.append(top) 12 if top[0] < a[i]: 13 ans[top[1]] = a[i] 14 _ = stack.pop() 15 else: 16 break 17 stack.append((a[i], i)) 18 return ans[:length] 19 20 #线段树 21 class Node(): 22 def __init__(self): 23 self.l = None 24 self.r = None 25 self.max = None 26 class Solution(object): 27 def get_bst(self,a,l,r): 28 n = Node() 29 if l==r: 30 n.max = a[l] 31 return n 32 mid = (l+r)//2 33 n.l = self.get_bst(a,l,mid) 34 n.r = self.get_bst(a,mid+1,r) 35 n.max = max(n.l.max,n.r.max) 36 return n 37 def query(self,root,a,l,r,ql,qr,x): 38 if l==r: 39 return root.max 40 #print(l,r) 41 if root.max < x: 42 return float('-inf') 43 mid = (l + r) // 2 44 if ql<=l and qr>=r: 45 if root.max >x: 46 vl = self.query(root.l,a,l,mid,ql,qr,x) 47 if vl>x: 48 return vl 49 vr = self.query(root.r,a,mid+1,r,ql,qr,x) 50 if vr>x: 51 return vr 52 else: 53 return float('-inf') 54 if ql<=mid : 55 vl = self.query(root.l,a,l,mid,ql,qr,x) 56 if vl>x: 57 return vl 58 if qr>mid: 59 vr = self.query(root.r,a,mid+1,r,ql,qr,x) 60 if vr >x: 61 return vr 62 return float('-inf') 63 64 def nextGreaterElements(self, nums): 65 if not nums: 66 return [] 67 length = len(nums) 68 a = nums[:]+nums[:] 69 y = [] 70 root = self.get_bst(a,0,len(a)-1) 71 for i in range(length): 72 x = self.query(root,a,0,len(a)-1,i+1,i+length-1,a[i]) 73 if x==float('-inf'): 74 y.append(-1) 75 else: 76 y.append(x) 77 return y
标签:return,nums,max,self,mid,503,LeetCode,root,线段 来源: https://www.cnblogs.com/ISGuXing/p/14500417.html