• [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_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 题目讲解汇总(持续更新中...)

  • 相关阅读:
    左偏树
    论在Windows下远程连接Ubuntu
    ZOJ 3711 Give Me Your Hand
    SGU 495. Kids and Prizes
    POJ 2151 Check the difficulty of problems
    CodeForces 148D. Bag of mice
    HDU 3631 Shortest Path
    HDU 1869 六度分离
    HDU 2544 最短路
    HDU 3584 Cube
  • 原文地址:https://www.cnblogs.com/grandyang/p/14383745.html
Copyright © 2020-2023  润新知