【栈】B019

    技术2023-03-25  116

    一、Problem

    给出一个以头节点 head 作为第一个节点的链表。链表中的节点分别编号为:node_1, node_2, node_3, … 。

    每个节点都可能有下一个更大值(next larger value):对于 node_i,如果其 next_larger(node_i) 是 node_j.val,那么就有 j > i 且 node_j.val > node_i.val,而 j 是可能的选项中最小的那个。如果不存在这样的 j,那么下一个更大值为 0 。

    返回整数答案数组 answer,其中 answer[i] = next_larger(node_{i+1}) 。

    注意:在下面的示例中,诸如 [2,1,5] 这样的输入(不是输出)是链表的序列化表示,其头节点的值为 2,第二个节点值为 1,第三个节点值为 5 。

    输入:[2,1,5] 输出:[5,5,0]

    提示:

    对于链表中的每个节点,1 <= node.val <= 10^9 给定列表的长度在 [0, 10000] 范围内

    二、Solution

    方法一:暴力

    class Solution { public int[] nextLargerNodes(ListNode head) { int n = 0, MAXN = (int) 1e6, a[] = new int[MAXN], p = 0, mv = 0; while (head != null) { a[p++] = head.val; head = head.next; n++; } int ans[] = new int[n]; for (int i = 0; i < n-1; i++) for (int j = i+1; j < n; j++) { if (a[j] > a[i]) { ans[i] = a[j]; break; } } return ans; } }

    复杂度分析

    时间复杂度: O ( n 2 ) O(n^2) O(n2),空间复杂度: O ( n ) O(n) O(n)

    方法二:单调栈

    思路

    因为我们要找的是最靠近的且比当前数 v 要大的,所以我们不能记录某一段区间中的最大值,我们要记录最新的且比当前数 v 要大的

    我们可以维护一个单调递减栈(自底向上数递减),始终维护栈顶元素是最靠近且比当前数 v 要大的

    class Solution { public int[] nextLargerNodes(ListNode head) { int n = 0, MAXN = (int) 1e6, a[] = new int[MAXN], p = 0; while (head != null) { a[p++] = head.val; head = head.next; n++; } int ans[] = new int[n]; Stack<Integer> st = new Stack<>(); for (int i = n-1; i >= 0; i--) { while (!st.isEmpty() && st.peek() <= a[i]) st.pop(); ans[i] = st.isEmpty() ? 0 : st.peek(); st.push(a[i]); } return ans; } }

    复杂度分析

    时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)
    Processed: 0.017, SQL: 10