一、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;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:單調棧
思路
因爲我們要找的是最靠近的且比當前數 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;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,