Force button brush questions ---- > single chain list series

# The first solution: operate on the original linked list and burn the brain version in the small red sun

/** * 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 removeElements(ListNode head, int val) { if(head== null) return head; ListNode cur=head; ListNode ahead=null; while(cur != null) { if(cur.next != null)//First, the current next is not empty { ahead = cur.next;//Call the pioneer node to move forward. This sentence ensures that the ahead is always one after the cur, followed by the new cur if(ahead.val == val)//If the value of the pioneer node is exactly equal to the target value { cur.next=ahead.next;//Connect across ahead nodes ahead = cur;//The pioneer node returns and waits for the next use. } } if(cur.next != null && cur.next.val != val) { cur = cur.next;//cur can move forward ahead = ahead.next; } if(cur.next == null) { if(head.val == val) return head.next; else break; } } return head; } }

For the solution of this problem, the supplementary explanations are as follows,

//First of all, in fact, there is a problem with the setting of loop invariants in my solution to this problem. In many cases, whether it is an array or a linked list

//Whether the pointer is fast or slow or the sliding window, in fact, most of them set the fast pointer to the end as the termination condition

//The loop invariant is set to cur. All the above operations are carried out in the while loop for cur.next is not empty, that is, the loop cannot go out when cur.next==null, so it needs to be processed!

//Cur can be moved only if the value of the next node of cur is not the target value. Therefore, at this step (cur.next==null), there is no need to check the val of cur

//Turn back and judge the head node! ~ ~, because it starts from cur and cur.next at the beginning. It just misses the first head node. Remember to return internally, or you will report an error loop! That is to say, you have found the wrong loop invariant and need to exit manually ~ it's too delicious

//Therefore, it is recommended that you use the fast moving pointer as the loop invariant to terminate the loop!

### According to this question, summarize the experience:

1: From the beginning, if the first header node is followed by a series of items that meet the requirements and need to be deleted, you are required to either keep returning the pointer to avoid continuously meeting the requirements, but the pointer keeps moving forward and misses:

Or skip the first header node, scan it again and look back at the second one

2: The while loop still needs to find the invariant condition of the loop, and the conditions for going out should be taken into account

In many cases, whether it is an array or a linked list

//Whether the pointer is fast or slow or the sliding window, in fact, most of them set the fast pointer to the end as the termination condition

Find the right conditions and get twice the result with half the effort

3: Secondly, if you start with a series of the same, it's better to start with the second and then go back to the first. This idea is really good.

Force button brush questions ---- > single chain list series

Question 1: remove linked list elements

# The second solution: operate on the original linked list, BOGO version

In a sense, this problem can be written as a deletion method in the addition, deletion, query and modification of a single linked list. remove is true and efficient.

Loop invariant changed!

/** * Definition for singly-linked list. * <p> * public class ListNode { * <p> * int val; * <p> * ListNode next; * <p> * ListNode() {} * <p> * ListNode(int val) { this.val = val; } * <p> * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * <p> * } */ class Solution { //BOGO solution public ListNode removeElements(ListNode head, int val) { if (head == null) return head;//Only here can we judge whether the linked list is empty. If the backhand is empty, the following reference variables will explode and cannot be declared ListNode cur = head;//Start to fix the fixed node for threading on the first one ListNode ahead = head.next;//Set the pioneer node at the second //Then come back and check the first node //If it is an extreme special judgment of 66666 val==6, it is too hard to check from the first, and the pioneer node needs to be returned continuously~ while (ahead != null) //There are three advantages of using ahead pioneer node as loop invariant //1: In the following two cases in the loop, no matter what, the position of the ahead is constantly changing. When the ahead is empty, the linked list is scanned once, and the complexity is n //2: If there is only one node, the ahead is empty and cannot enter the loop. { if (ahead.val == val)//If the value of the pioneer node is the target value, skip this node first, and then wear it with the fixed one { ahead = ahead.next; cur.next = ahead; } else//The pioneer node is safe. Go ahead and judge the value of the new ahead in the next cycle { cur = cur.next; ahead = ahead.next; } }//Out of the loop, and then judge the head node if (head.val == val) { return head.next; } return head; } }

# The third solution: on the violent solution of linked list! And its easy to appear and occur bug s

- ðŸ”² Don't forget to declare that the new array is added after the node applies for copy

Big brother Li Kou and sister Gong Shui Sanye said that the violent solution of the linked list can solve 90% of the problems,

The template is to apply for a new header node! ListNode newHead = new ListNode (- 10), finally return the next of the new header node, and then continuously copy new nodes that do not meet the conditions to add to the new linked list, and finally return~~

This topic: force button brush question ---- > single chain list series

Question 1: remove linked list elements

The third solution: apply for the linked list, update dynamically in the back, and add the new nodes that meet the requirements in the original linked list

My understanding is not deep, the first time I hit the error code by hand!

Attention is wrong. Let's take a look and find out the mistakes. Just try it. Don't go up~

/** * Definition for singly-linked list. * <p> * public class ListNode { * <p> * int val; * <p> * ListNode next; * <p> * ListNode() {} * <p> * ListNode(int val) { this.val = val; } * <p> * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * <p> * } */ class Solution { public ListNode removeElements(ListNode head, int val) { if (head == null) return head; ListNode cur = head; ListNode newHead = new ListNode(-10); ListNode temp = newHead; while (cur != null) { if (cur.val != val) { temp.next = cur; temp = temp.next; } cur = cur.next; } return newHead.next; } }

So I'm a real dish! Then the third solution~

/** * Definition for singly-linked list. * <p> * public class ListNode { * <p> * int val; * <p> * ListNode next; * <p> * ListNode() {} * <p> * ListNode(int val) { this.val = val; } * <p> * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * <p> * } */ class Solution { public ListNode removeElements(ListNode head, int val) { if (head == null) { return head; } ListNode newHead = new ListNode(-10); ListNode temp = newHead; ListNode cur = head; while (cur != null) { if (cur.val != val) { ListNode node = new ListNode(cur.val); temp.next = node; temp = temp.next; } cur = cur.next; } return newHead.next; } }

Â

Â