We are given a linked list with head
as the first node. Let's number the nodes in the list: node_1, node_2, node_3, ...
etc.
Each node may have a next larger value: for node_i
, next_larger(node_i)
is the node_j.val
such that j > i
, node_j.val > node_i.val
, and j
is the smallest possible choice. If such a j
does not exist, the next larger value is 0
.
Return an array of integers answer
, where answer[i] = next_larger(node_{i+1})
.
Note that in the example inputs (not outputs) below, arrays such as [2,1,5]
represent the serialization of a linked list with a head node value of 2, second node value of 1, and third node value of 5.
Example 1:
Input: [2,1,5]
Output: [5,5,0]
Example 2:
Input: [2,7,4,3,5]
Output: [7,0,5,5,0]
Example 3:
Input: [1,7,5,1,9,2,5,1]
Output: [7,9,9,9,0,5,0,0]
Note:
1 <= node.val <= 10^9
for each node in the linked list.- The given list has length in the range
[0, 10000]
.
這道題給了一個鏈表,讓找出每個結點值的下一個較大的結點值,跟之前的 Next Greater Element I,Next Greater Element II,和 Next Greater Element III 很類似,不同的是這里不是數組,而是鏈表,就稍稍的增加了一些難度,因為鏈表無法直接根據下標訪問元素,在遍歷鏈表之前甚至不知道總共有多少個結點。但是無妨,整個思路還是一樣的,當然最簡單暴力的解法,就是對於每個結點,都遍歷后面的所有結點,找出第一個大於的結點值,但這種平方級時間復雜度的解法基本上是無法通過 OJ 的,畢竟這是一道 Medium 難度的題目。這時候就要祭出單調棧這個大殺器了,可以參見博主之前的總結貼 LeetCode Monotonous Stack Summary 單調棧小結,基本上來說,為了達到線性的時間復雜度,這里需要維護一個單調遞減的棧,若當前的數字小於等於棧頂元素,則加入棧,若當前數字大於棧頂元素,非常棒,說明棧頂元素的下一個較大數字找到了,標記上,且把棧頂元素移除,繼續判斷下一個棧頂元素和當前元素的關系,直到當前數字小於等於棧頂元素為止。通過這種方法,就可以在線性的時間內找出所有數字的下一個較大的數字了。思路有了,下面來看具體的代碼,這里新建兩個數組,res 和 nums 分別保存要求的結果和鏈表的所有結點值,還需要一個棧 st 和一個變量 cnt(記錄當前的數組坐標),然后開始遍歷鏈表,首先把當前結點值加入數組 nums,然后開始循環,若棧不空,且當前結點值大於棧頂元素(注意這里單調棧存的並不是結點值,而是該值在 nums 數組中的坐標值,這是為了更好的在結果 res 中定位),此時用該結點值來更新結果 res 中的對應的位置,然后將棧頂元素移除,繼續循環直到條件不滿足位置。然后把當前的坐標加入棧中,此時還要更新結果 res 的大小,因為由於鏈表的大小未知,無法直接初始化 res 的大小,當然我們可以在開頭的時候先遍歷一遍鏈表,得到結點的個數也是可以的,參見代碼如下:
class Solution {
public:
vector<int> nextLargerNodes(ListNode* head) {
vector<int> res, nums;
stack<int> st;
int cnt = 0;
while (head) {
nums.push_back(head->val);
while (!st.empty() && head->val > nums[st.top()]) {
res[st.top()] = head->val;
st.pop();
}
st.push(cnt);
res.resize(++cnt);
head = head->next;
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1019
類似題目:
參考資料:
https://leetcode.com/problems/next-greater-node-in-linked-list/
https://leetcode.com/problems/next-greater-node-in-linked-list/discuss/265548/C%2B%2B-O(n)-stack