虚拟头结点法
在头节点需要进行判断时,可以使用虚拟头节点,此时虚拟节点的next指向头结点。虚拟头结点在许多题目中都可以采用。
题目描述:
移除链表元素(力扣链接🔗)

题目分析:
删除节点的思路:

此时头结点需要判断,所以右两种方法:
- 直接使用原来的链表来进行删除操作。
 - 设置一个虚拟头结点在进行删除操作。
 
解法一:
在原来的链表删除。

移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。

代码:
不添加虚拟节点方式
时间复杂度 O(n) , 空间复杂度 O(1)
public ListNode removeElements(ListNode head, int val) {// 不使用虚拟的头节点的方法// 先将前面相等的移除,也就是移除头结点while (head != null && head.val == val) {head = head.next;}// 已经为空,提前退出if (head == null) {return head;}ListNode pre = head;ListNode cur = head.next;// 循环遍历移除while (cur != null) {if (cur.val == val) {// 删除此节点pre.next = cur.next;} else {pre = cur;}cur = cur.next;}return head;}
解法二:
设置虚拟头节点

这里来给链表添加一个虚拟头结点为新的头结点,此时要移除这个旧头结点元素1。注意最后返回虚拟头节点的next。
代码:
public ListNode removeElements(ListNode head, int val) {// 为空直接返回if (head == null) {return head;}ListNode dummy = new ListNode(-1, head); // 虚拟头结点ListNode pre = dummy;ListNode cur = dummy.next;while (cur != null) {if (cur.val == val) {pre.next = cur.next;} else {// 移动前指针到后指针的位置pre = cur;}cur = cur.next;}return dummy.next;}}
其他虚拟头结点案例
两两交换链表中的节点(🔗)
