【Leetcode】1019. Next Greater Node In Linked List

题目地址:

https://leetcode.com/problems/next-greater-node-in-linked-list/

链表版本的求下一个更大元素。还是用单调栈。维护一个单调下降的栈,如果栈空或者栈顶元素大于等于下一个来的元素,就把下一个来的元素入栈;否则一旦遇到比栈顶元素更大的元素,就说明栈顶元素的下一个更大元素就是要来的这个,记录一下并pop栈顶,然后继续check,直到栈的单调性重新满足。

基本思路是上面这样的,然而这题与数组的不同的地方在于,如果栈里存放的是node的下标,就会造成因为没有random access而无法知道该下标对应的值是多少;如果存放值,就无法知道该值的下标是多少。这里我们有两个方案:

法1:用两个栈,一个存放下标,另一个存放值。代码如下:

import java.util.*;

class Solution {
    public int[] nextLargerNodes(ListNode head) {
        if (head == null) {
            return new int[0];
        }
        
        // 先求一下链表长度
        int len = 1;
        ListNode cur = head;
        while (cur.next != null) {
            len++;
            cur = cur.next;
        }
        // 初始化一个数组
        int[] res = new int[len];
        
    	// 一个栈专门存放值,另一个专门存放下标
        Deque<Integer> stackVal = new LinkedList<>();
        Deque<Integer> stackInd = new LinkedList<>();
        // 用一个变量记录一下链表每个node的下标
        int ind = 0;
        while (head != null) {
        	// 下面的逻辑就是很简单的单调栈的思路
            while (!stackInd.isEmpty() && stackVal.peek() < head.val) {
                res[stackInd.pop()] = head.val;
                stackVal.pop();
            }
            stackInd.push(ind++);
            stackVal.push(head.val);
            head = head.next;
        }
        
        return res;
    }
}

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}

时空复杂度 O ( n ) O(n) O(n)

法2:用一个ArrayList来存放链表的值。这样就解决了random access的问题。但需要注意的是,最后需要把没有下一个更大元素的值置零。

import java.util.*;

public class Solution {
    public int[] nextLargerNodes(ListNode head) {
        if (head == null) {
            return new int[0];
        }
    	// list专门存放链表的值,stack存放下标
        List<Integer> list = new ArrayList<>();
        Deque<Integer> stack = new LinkedList<>();
        
        int ind = 0;
        while (head != null) {
            list.add(head.val);
            while (!stack.isEmpty() && list.get(stack.peek()) < head.val) {
            	// 如果出现了更大元素,就直接把list的对应位置的数改成那个更大元素
                list.set(stack.pop(), head.val);
            }
            stack.push(ind++);
            head = head.next;
        }
        // 接下来有一些没有更大元素的元素,需要将它们置零
        while (!stack.isEmpty()) {
            list.set(stack.pop(), 0);
        }
        // 最后开一个数组用来返回
        int[] res = new int[list.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = list.get(i);
        }
        
        return res;
    }
}

时空复杂度 O ( n ) O(n) O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值