【棧】B019_LC_鏈表中的下一個最近的更大節點(暴力 / 單調棧)

一、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(n2)O(n^2)
  • 空間複雜度: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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章