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_inext_larger(node_i) is the node_j.val such that j > inode_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. 1 <= node.val <= 10^9 for each node in the linked list.
  2. The given list has length in the range [0, 10000].

这道题给了一个链表,让找出每个结点值的下一个较大的结点值,跟之前的 Next Greater Element INext 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

类似题目:

Next Greater Element I

Next Greater Element II

Next Greater Element III

参考资料:

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

https://leetcode.com/problems/next-greater-node-in-linked-list/discuss/265508/JavaC%2B%2BPython-Next-Greater-Element

LeetCode All in One 题目讲解汇总(持续更新中…)


转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com

💰


微信打赏


Venmo 打赏

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,试运营期间前五十位可享受半价优惠~)

×

Help us with donation