题目链接
Leetcode.2487 从链表中移除节点 Rating : 1455
题目描述
给你一个链表的头节点 head 。
对于列表中的每个节点 node ,如果其右侧存在一个具有 严格更大 值的节点,则移除 node 。
返回修改后链表的头节点 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 , 1 0 5 ] [1, 10^5] [1,105] 内
- 1 < = N o d e . v a l < = 1 0 5 1 <= Node.val <= 10^5 1<=Node.val<=105
解法:单调栈
对于 节点 n o d e i nodei nodei 如果后面存在 节点 n o d e j nodej nodej,使得 n o d e j − > v a l > n o d e i − > v a l nodej->val > nodei->val nodej−>val>nodei−>val,那么就删除节点 n o d e i nodei nodei。
我们用 单调栈 完成。
时间复杂度: O ( n ) O(n) O(n)
C++代码:
class Solution {
public:
ListNode* removeNodes(ListNode* head) {
vector<int> stk;
while(head){
//stk.back() < head->val 说明当前节点值 head->val 更大,所以要删除 stk.back() 节点
while(!stk.empty() && stk.back() < head->val) stk.pop_back();
stk.push_back(head->val);
head = head->next;
}
ListNode* cur = new ListNode(stk[0]);
ListNode * p =cur;
for(int i = 1;i < stk.size();i++){
p->next = new ListNode(stk[i]);
p = p->next;
}
return cur;
}
};