203.移除链表元素

题意:删除链表中等于给定值 val 的所有节点。

示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:
输入:head = [], val = 1
输出:[]

示例 3:
输入:head = [7,7,7,7], val = 7
输出:[]

思路:

方法一:递归

方法二:迭代
删除链表中给定值的节点,一般的步骤是:

遍历链表找到所有值为 val 的节点;

将值为 val 的节点的上一个节点直接指向该节点的下一个节点(pre->next = pre->next->next)。

 

 

方法三:双指针
解题步骤:

 

设置两个均指向头节点的指针,pre(记录待删除节点的前一节点)和 cur (记录当前节点);

 

遍历整个链表,查找节点值为 val 的节点,找到即删除该节点,否则继续查找。

 

2.1 找到,将当前节点的前一节点(之前最近一个值不等于 val 的节点(pre))连接到当前节点(cur)的下一个节点(即将 pre 的下一节点指向 cur 的下一节点:pre->next = cur->next)。

 

2.2 没找到,更新最近一个值不等于 val 的节点(即 pre = cur),并继续遍历(cur = cur->next)。

 

方法四:虚拟头节点(哨兵)
前三种方法均需要判断头节点是否为待删除的节点,且处理头节点的代码逻辑与其它节点特别相似,有没有方法使得代码更优美并且能避免对头节点的判断呢?

答案是有的。可以通过在头节点前增加虚拟头节点,这样头节点就成了普通节点,不需要单独拎出来考虑,但是在返回的时候,返回的是虚拟头节点的下一节点而不是虚拟头节点。

 

方法五:栈

本题还可以采用栈去做。

  1. 将值不等于 val 的节点依次压入栈中;

  2. 将压入栈的节点重新连接,栈底的节点作为新的头节点返回

复制代码
  1 #include<vector>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<numeric>
  5 #include<iterator>
  6 #include<stack>
  7 using namespace std;
  8 
  9  struct ListNode {
 10      int val;
 11      ListNode *next; 
 12      ListNode() : val(0), next(nullptr) {}
 13      ListNode(int x) : val(x), next(nullptr) {}
 14      ListNode(int x, ListNode *next) : val(x), next(next) {}
 15  };
 16 
 17 class Solution {
 18 public:
 19     ListNode* removeElements_doublezhizhen(ListNode* head, int val) 
 20     {
 21         while(head!=nullptr && head->val==val)
 22         {
 23             head = head->next;
 24         }
 25         if (head == nullptr) return head;
 26         ListNode* pre = head;
 27         ListNode* cur = head;
 28         while(cur != nullptr)
 29         {
 30             cur = cur->next;
 31             if(cur->val == val)
 32             {
 33                 pre->next = cur->next;
 34                 cur = pre->next;
 35             }
 36             else
 37             {
 38                 pre = pre->next;
 39             }
 40         }
 41         return head;
 42     }
 43     ListNode* removeElements_digui(ListNode* head, int val)
 44     {
 45         if(head == nullptr)
 46         {
 47             return head;
 48         }
 49         head->next = removeElements_digui(head->next,val);
 50         return head->val == val? head->next:head;
 51     }
 52     ListNode* removeElements_diedai(ListNode* head, int val)
 53     {
 54         while(head!=nullptr&&head->val==val)
 55         {
 56             head = head->next;
 57         }
 58         if(head==nullptr)
 59         {
 60             return head;
 61         }
 62         ListNode*pre = head;
 63         while(pre->next!=nullptr)
 64         {
 65             if(pre->next->val==val)
 66             {
 67                 pre->next = pre->next->next;
 68             }
 69             else
 70             {
 71                 pre = pre->next;
 72             }
 73         }
 74         return head;
 75     }
 76     ListNode* removeElements_dummyhead(ListNode* head, int val)
 77     {
 78         ListNode* dummy_head = new ListNode(0,head);
 79         ListNode* cur = dummy_head;
 80         while(cur->next)
 81         {
 82             if(cur->next->val==val)
 83             {
 84                 ListNode* delete_node = cur->next;
 85                 cur->next = delete_node->next;
 86                 delete delete_node;
 87             }
 88             else
 89             {
 90                 cur = cur->next;
 91             }
 92         }  
 93         ListNode* res = dummy_head->next;
 94         delete dummy_head;
 95         return res;
 96     }
 97     ListNode* removeElements_stack(ListNode* head, int val)
 98     {
 99         stack<ListNode*>* sta = new stack<ListNode*>();
100         while(head!=nullptr)
101         {
102             if(head->val!=val)
103             {
104                 (*sta).push(head);
105             }
106             head = head->next;
107         }
108         while(!(*sta).empty())
109         {
110             ((*sta).top())->next = head;
111             head = (*sta).top();
112             (*sta).pop();
113         }
114         return head;
115     }
116 };
117 
118 int main() {
119     ListNode* head = new ListNode();
120     ListNode* r = nullptr;
121     vector<int> num = { 1,2,7,7,7,7 };
122     for (int i =num.size()-1;i>=0;i--)
123     {
124         ListNode* a = new ListNode(num[i],r);
125         head->next = a;
126         r = a;
127     }
128     for (auto p = head->next; p != nullptr; p = p->next) 
129     {
130         cout << p->val;
131     }
132     cout << endl;
133     ListNode* res = new ListNode();
134     Solution a;
135     res = a.removeElements_stack(head,7);
136     for (auto p = head->next; p != nullptr; p = p->next) 
137     {
138         cout << head->next->val;
139         head = head->next;
140     }
141     cout << endl;
142     system("pause");
143 }
复制代码

 

posted @   xiazichengxi  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
主题色彩