leedcode :203 题
需求:
给你一个链表的头节点 head
和一个整数 val
,删除链表中所有满足 Node.val == val
的节点。
graph LR
1(node1)
2(node2)
3(node3)
1 --> 2 -->3
删除链表中的的某一个元素,我们只需要将被删除节点的前一个元素,指向被删除节点的后一个元素,记得释放node2的内存(如果需要)。比如删除节点2:
graph LR
1(node1)
2(node2)
3(node3)
1 -- 2:重新指向3 --> 3
1 -- 1:删除--> 2 -->3
如果是删除头节点(node1)呢?
head = head ->next ;
将头节点指向node2 ,然后将node1删除。
graph LR
1(node1)
2(node2)
3(node3)
1 --> 2 -->3
4(node1)
5(node2)
6(node3)
4 <--删除--> 5 -->6
以上可以发现,针对头节点和非头节点,移除方式是不一样的。
这种实现方法需要判断删除节点是否是头节点。
使用虚拟头节点
graph LR
v(虚拟)
1(node1)
2(node2)
3(node3)
v --> 1 --> 2 -->3
这样就可以使用统一的方式删除节点了。即将被删除节点的前一个元素,指向被删除节点的后一个元素。
原链表删除代码实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode RemoveElements(ListNode head, int val) {
//需要while循环,因为链表可能为 [1]-[1]-[1]
//删除了当前头节点,然后新的头节点也可能是符合的。
while(head != null && head.val == val)
{
head = head.next;
}
var current = head;
while (current !=null && current.next !=null)
{
if(current.next.val == val)
{
current.next = current.next.next;
}
else
{
current = current.next;
}
}
return head;
}
}
使用虚拟头节点代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode RemoveElements(ListNode head, int val) {
var dummy = new ListNode();
dummy.next = head;
var current = dummy;
while(current != null && current.next != null)
{
if (current.next.val == val)
{
current.next = current.next.next;
}
else
{
current = current.next;
}
}
return dummy.next;
}
}