LC.P1019[链表中的下一个更大节点]
思路
利用单调栈,从右到左遍历链表的数据,若栈顶元素$<=$当前遍历到的元素,则弹出栈。
若栈中仍有元素,则存在下一个更大的节点;否则为0。
方法一:单调栈(List实现反转)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
class Solution { public int[] nextLargerNodes(ListNode head) { List<Integer> list = new ArrayList<>(); while (head != null) { list.add(head.val); head = head.next; } int n = list.size(); int[] ans = new int[n]; Deque<Integer> stack = new ArrayDeque<>(); for (int i = n - 1; i >= 0; --i) { int num = list.get(i); while (!stack.isEmpty() && stack.peek() <= num) stack.pop(); if (!stack.isEmpty()) ans[i] = stack.peek(); stack.push(num); } return ans; } }
|
- 时间复杂度:$O(n)$
- 空间复杂度:$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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
class Solution { int n;
public int[] nextLargerNodes(ListNode head) { head = reverse(head); int[] ans = new int[n]; Deque<Integer> stack = new ArrayDeque<>(); while (head != null) { int num = head.val; --n; while (!stack.isEmpty() && stack.peek() <= num) stack.pop(); if (!stack.isEmpty()) ans[n] = stack.peek(); stack.push(num); head = head.next; } return ans; }
private ListNode reverse(ListNode head) { ListNode pre = null, cur = head; while (cur != null) { ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; ++n; } return pre; } }
|
- 时间复杂度:$O(n)$
- 空间复杂度:$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 25 26 27 28 29 30 31 32 33 34 35 36 37
|
class Solution { int[] ans; Deque<Integer> stack;
public int[] nextLargerNodes(ListNode head) { stack = new ArrayDeque<>(); func(head, 0); return ans; }
private void func(ListNode node, int n) { if (node == null) { ans = new int[n]; return; } func(node.next, n + 1); while (!stack.isEmpty() && stack.peek() <= node.val) stack.pop(); if (!stack.isEmpty()) ans[n] = stack.peek(); stack.push(node.val); } }
|
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$