链表中的下一个更大节点
难度:
标签:
题目描述
给定一个长度为 n
的链表 head
对于列表中的每个节点,查找下一个 更大节点 的值。也就是说,对于每个节点,找到它旁边的第一个节点的值,这个节点的值 严格大于 它的值。
返回一个整数数组 answer
,其中 answer[i]
是第 i
个节点( 从1开始 )的下一个更大的节点的值。如果第 i
个节点没有下一个更大的节点,设置 answer[i] = 0
。
示例 1:
输入:head = [2,1,5] 输出:[5,5,0]
示例 2:
输入:head = [2,7,4,3,5] 输出:[7,0,5,5,0]
提示:
- 链表中节点数为
n
1 <= n <= 104
1 <= Node.val <= 109
代码结果
运行时间: 99 ms, 内存: 19.2 MB
/*
* 思路:
* 使用Stream API的方式与常规方法类似,但更简洁。
* 我们依然需要用栈来记录和查找下一个更大节点。
*/
import java.util.*;
import java.util.stream.*;
public class NextGreaterNodeInLinkedListStream {
static class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public int[] nextLargerNodes(ListNode head) {
List<ListNode> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
int n = list.size();
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
IntStream.range(0, n).forEach(i -> {
while (!stack.isEmpty() && list.get(stack.peek()).val < list.get(i).val) {
result[stack.pop()] = list.get(i).val;
}
stack.push(i);
});
return result;
}
}
解释
方法:
这个解决方案首先将链表的值转换为一个列表,然后利用单调栈解决'下一个更大的元素'问题。通过遍历链表将所有值存储在列表中,随后使用单调栈技术来快速查找每个元素右侧第一个更大的值。遍历值列表时,对于每个元素,检查栈顶元素是否代表一个较小的值。如果是,栈顶元素出栈并更新结果数组,表明找到了较小元素右侧的更大值。如果当前元素不比栈顶元素大,或栈为空,则当前元素索引入栈。这样确保栈内元素始终保持单调递减。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么单调栈要保持元素索引的单调递减,这样的设计有什么特别的优势?
▷🦆
在实现单调栈时使用的循环结构`while st and val > val_list[st[-1]]`,如果栈中元素很少但列表很大会怎样影响性能?
▷🦆
函数返回的数组`res`初始化为全0,这种方式是否总是合理的,尤其是在所有链表元素都没有更大值的情况下?
▷🦆
链表转数组的方法对于非常长的链表有无效率或实用性的问题?
▷