题目:LeetCode 2487
解法
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNodes(ListNode* head) {
vector<ListNode*> stk;
ListNode* demmy = new ListNode(1000000,head);
stk.push_back(demmy);
while(head){
while(stk.back()->val<head->val){
stk.pop_back();
}
stk.push_back(head);
head = head->next;
}
for(int i=0;i<stk.size()-1;i++){
stk[i]->next = stk[i+1];
}
stk.back()->next=NULL;//这个不用写,最终数组的栈顶元素一定是初始链表的尾节点,一定指向NULL。
return demmy->next;//应返回的是链表节点而非数组
}
};
这个题目让我意识到了,vector不仅可以构建顺序表来实现栈,而且可以构建链表来实现栈,因为不论是栈、顺序表还是链表,他们本质上都是数组,所以本质就是利用vector来构建数组,然后利用数组来模拟栈。
这个题目思路是,首先构建一个链表,即数据类型为节点(结构体指针)的数组,然后定义一个虚拟头节点,特点是不会被移除,所以必须比题目给出的节点数据域都大,然后我们将这个demmy入栈,随后利用while循环遍历链表,在遍历过程中实现以下操作:
cpp
while(stk.back()->val<head->val){
stk.pop_back();
}
stk.push_back(head);
在这几行语句中,我们要实现的操作是,将每一个节点传入栈中,但是在这之前,让待传入节点与栈顶元素作比较,如果大于栈顶元素,则弹出栈顶元素,重复判断和弹出操作,来实现对小节点的移除,最终栈就会变成一个单调不增的链表。
然后利用while循环,使这个链表串联起来,即让每个节点的next指针指向后者,最后一个节点指向NULL,(最后一个节点一定指向NULL,不用单独操作,最终数组的栈顶元素一定是初始链表的尾节点,一定指向NULL。)