给你一个链表的头节点 head
。
移除每个右侧有一个更大数值的节点。
返回修改后链表的头节点 head
。
示例 1:
输入:head = [5,2,13,3,8]
输出:[13,8]
解释:需要移除的节点是 5 ,2 和 3 。
- 节点 13 在节点 5 右侧。
- 节点 13 在节点 2 右侧。
- 节点 8 在节点 3 右侧。
示例 2:
输入:head = [1,1,1,1]
输出:[1,1,1,1]
解释:每个节点的值都是 1 ,所以没有需要移除的节点。
提示:
[1, 10^5]
内1 <= Node.val <= 10^5
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNodes(ListNode head) {
}
}
栈(先进后出)
2024年第一篇博客, 开始喽~
言归正传, 对于这个题目, 我们应该尝试使用栈的方式, 在遍历链表的过程中, 我们需要用栈的形式存储每一个链表节点, 并且为了方便后期的组装, 我们可以尝试双向队列来代替链表, 以便于后边后期从栈底取出元素.
ArrayDeque<ListNode> deque = new ArrayDeque<ListNode>();
那么什么时候触发删除操作呢? 如果当前节点的值比上一个节点的值大时, 也就是题意中的 每个右侧有一个更大数值的节点
, 我们就从双向队列的栈顶依次取值, 直到不满足栈顶的值不大于当前节点的值.
if (head.val > lastValue) {
ListNode lastNode = deque.peekFirst();
while (lastNode != null && lastNode.val < head.val) {
deque.pollFirst();
lastNode = deque.peekFirst();
}
}
然后就是利用双向队列来重组链表了, 我们需要依次从栈底抛出节点然后组装链表.
ListNode resultHeader = null, nowNode = null;
while (!deque.isEmpty()) {
ListNode node = deque.pollLast();
if (resultHeader == null) {
resultHeader = node;
nowNode = node;
} else {
nowNode.next = node;
nowNode = nowNode.next;
}
}
接下来, 我们就看一下整体的题解过程.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNodes(ListNode head) {
// 用栈实现, 先入栈后出栈
ArrayDeque<ListNode> deque = new ArrayDeque<ListNode>();
int lastValue = 0;
while (head != null) {
if (head.val > lastValue) {
ListNode lastNode = deque.peekFirst();
while (lastNode != null && lastNode.val < head.val) {
deque.pollFirst();
lastNode = deque.peekFirst();
}
}
deque.addFirst(head);
lastValue = head.val;
head = head.next;
}
// 搞定之后重组链表
ListNode resultHeader = null, nowNode = null;
while (!deque.isEmpty()) {
ListNode node = deque.pollLast();
if (resultHeader == null) {
resultHeader = node;
nowNode = node;
} else {
nowNode.next = node;
nowNode = nowNode.next;
}
}
return resultHeader;
}
}
复杂度分析:
结果如下所示.