【刷题打卡】1019. 链表中的下一个更大节点

124 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1019. 链表中的下一个更大节点 - 力扣(LeetCode) (leetcode-cn.com)

给定一个长度为 n 的链表 head

对于列表中的每个节点,查找下一个 更大节点 的值。也就是说,对于每个节点,找到它旁边的第一个节点的值,这个节点的值 严格大于 它的值。

返回一个整数数组 answer ,其中 answer[i] 是第 i 个节点( 从1开始 )的下一个更大的节点的值。如果第 i 个节点没有下一个更大的节点,设置 answer[i] = 0 。

  示例 1:

image.png

输入:head = [2,1,5]
输出:[5,5,0]

示例 2:

image.png

输入:head = [2,7,4,3,5]
输出:[7,0,5,5,0]

提示:

  • 链表中节点数为 n
  • 1 <= n <= 10^4
  • 1 <= Node.val <= 10^9

二、思路分析:

  1. indexList 若是下一个元素比它大则存储下一个元素下标值,否则存0;在后续再次遍历填充结果数组时,会对于所存下标为0的位置进行更新;
  2. headList 按顺序存储原链表的val值
  3. 比如indexList.get(6)值为8,表示headList(6)的下一个更大节点值为headList(8)。

三、AC 代码:

public static int[] nextLargerNodes(ListNode head) {

    List<Integer> indexList = new ArrayList<>();
    List<Integer> headList = new ArrayList<>();
    ListNode p = head;
    int count = 0;
    while (p != null) {
        count++;
        if (p.next != null && p.next.val > p.val) {
            indexList.add(count);
        } else {
            indexList.add(0);
        }
        headList.add(p.val);
        p = p.next;
    }
    int[] rstArray = new int[count];
    int index = 0, j = 0;
    // 从倒数第二个元素开始,反向遍历并填充结果数组
    for (int i = count - 2; i >= 0; i--) {
        index = indexList.get(i);
        if (index != 0) {
            rstArray[i] = headList.get(index);
            j = index;
        } else {
            while (j != 0 && headList.get(j) <= headList.get(i)) {
                // 以下标链式的方式,找到第一个比当前元素大的值。
                j = indexList.get(j);
            }
            // 将比当前元素大的值的下标记录
            indexList.set(i, j);
            rstArray[i] = (j == 0) ? 0 : headList.get(j);
        }
    }
    indexList.clear();
    headList.clear();
    return rstArray;
}

四、总结:

时间复杂度 O(n)

对链表遍历一次; 对indexList遍历一次,遍历indexList时可能会触发对下标链的查找。考虑极端情况,链表为[n,1,2,3,...,n-1],遍历到i=0时,查找下标链长度n-1,其余查找长度1,总查找长度2n-2,时间复杂度O(n)

空间复杂度 O(n)

两个大小为n的列表,一个大小为n的数组。