[LeetCode] 1019. Next Greater Node In Linked List 链表中的下一个较大的结点
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