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

 

posted @ 2021-03-08 16:29  ISGuXing  阅读(121)  评论(0编辑  收藏  举报