/** * 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* removeElements(ListNode* head, int val) { ListNode* p = head; ListNode* frontP = head; //ListNode* temp = NULL; ListNode* ans = NULL; while(p != NULL){ //Now there is a problem. If you delete a node, you need to use the pointer of the previous node of the current node //To equal the pointer in the current node //Here is a one-way linked list. How to get the pointer of the previous node is a problem. //Find a variable to save. The first case is special. Deal with it specially //so what? For the first time, if two pointers move forward, then p move forward //When p and frontP are on the same node, //If yes, use two pointers to complete the deletion. If not, move forward at the same time //if(p == head && frontP == head){ if(p == frontP){//The above judgment condition cannot be used here, because when the first is the target value, //Then the next two pointers should move to the second. At this time, we have to make this special judgment, //If the first one is used, no special judgment will be made, and only one judgment will be made at the beginning //The first time it happens to be the target value, the ans has never received an assignment and is still initialized null //Initial cases are handled separately if(p->val == val){//*p.val, just understand and use it yourself. When using it, directly change it to - > //temp = p;// Since the delete code below cannot be added, this is unnecessary frontP = p->next; p = p->next; //delete temp;// An error will be reported with this line of code } else{ p = p->next; ans = frontP; } continue; } if(p->val == val){ //temp = p; //frontP = p->next; frontP->next = p->next;//This is to change the original linked list. According to the above writing, the linked list will not change at all p = p->next; //delete temp; } else{ frontP = p; p = p->next; } } return ans; } };

When doing this problem, first of all, it's a good habit to sort out your ideas first, and then do it. Secondly, the control of some critical situations is still a little lacking. Another problem is that delete will report an error.

There are two ways to answer this question: (standard answer on the official website)

class Solution { public: ListNode* removeElements(ListNode* head, int val) { if (head == nullptr) { return head; } head->next = removeElements(head->next, val); return head->val == val ? head->next : head; } }; Author: LeetCode-Solution Link: https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode-sol-654m/ Source: force buckle( LeetCode) The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

This is a recursive version. When to use recursion first? You have thought about a solution to simplify the problem first, and then the simplified part can still be simplified with the same idea.

This is the special processing of the first head node, and then the subsequent deletion operation. The subsequent deletion processing can be regarded as the head node to delete in the way of special processing.

class Solution { public: ListNode* removeElements(ListNode* head, int val) { struct ListNode* dummyHead = new ListNode(0, head); struct ListNode* temp = dummyHead; while (temp->next != NULL) { if (temp->next->val == val) { temp->next = temp->next->next; } else { temp = temp->next; } } return dummyHead->next; } }; Author: LeetCode-Solution Link: https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode-sol-654m/ Source: force buckle( LeetCode) The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

Method 2 is iteration. The difference from my own solution is that it only uses one pointer. Because I analyzed in my mind that it is necessary to point the previous node of the current node to the next node of the current node, and the characteristic of the single linked list is that it is difficult to obtain the pointer to the previous node of the current node, and the next one is more points. When There is no need to use a pointer to point to the previous node, so you only need to use a pointer variable to point to the previous node of the current node. Then the problem comes, there is nothing in front of the first node. This is the difference between you and the answer. If the answer creates a node, it will be created if it doesn't.

Three points: 1. Traversal does not necessarily have to have a pointer, but a variable maintains the current subscript

2. The single linked list is easy from the front to the back, otherwise it is difficult. Therefore, when the two have a choice, you can choose the former one.

3. Lack of conditions, inconsistent conditions, you create conditions for him to unify the situation, so it is more convenient to deal with it. Isn't this the fucking advantage of forming a two-way linked list into a ring?