LC.P2454[下一个更大元素IV]

方法一:排序+有序集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int[] secondGreaterElement(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
int[][] arr = new int[n][2];
for (int i = 0; i < n; ++i) {
arr[i] = new int[]{nums[i], i};
}
Arrays.sort(arr, (a, b) -> b[0] - a[0]);
TreeSet<Integer> ts = new TreeSet<>();
for (int[] p : arr) {
int i = p[1];
Integer j = ts.higher(i);
if (j != null && ts.higher(j) != null) {
ans[i] = nums[ts.higher(j)];
}
ts.add(i);
}
return ans;
}
}
  • 时间复杂度:$O(nlogn)$
  • 空间复杂度:$O(n)$

方法二:双单调栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int[] secondGreaterElement(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
List<Integer> s = new ArrayList<>(), t = new ArrayList<>();
for (int i = 0; i < n; ++i) {
int x = nums[i];
while (!t.isEmpty() && nums[t.get(t.size() - 1)] < x) {
ans[t.get(t.size() - 1)] = x; // t 栈顶的下下个更大元素是 x
t.remove(t.size() - 1);
}
int j = s.size();
while (j > 0 && nums[s.get(j - 1)] < x) {
j--; // s 栈顶的下一个更大元素是 x
}
List<Integer> popped = s.subList(j, s.size());
t.addAll(popped); // 把从 s 弹出的这一整段元素加到 t
popped.clear(); // 弹出一整段元素
s.add(i); // 当前元素的下标加到 s 栈顶
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$