前驱知识:列表节点的定义
1. 单链表的定义
Java代码如下:
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;
}
}
思路1:虚拟头节点 + pre指针
思路1:为了保证后续操作中对于头节点的操作和非头节点操作的一致性,这里创建一个虚拟 dummy 头节点,将待操作的链表连接在该虚拟头节点后面 ListNode dummy = new ListNode(-1, head);该方法需要一个pre节点和虚拟头节点。
Java代码如下:
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return head;
}
ListNode dummy = new ListNode(-1, head); // 创建虚拟的头节点
ListNode cur = head; // 当前节点
ListNode pre = dummy; // 当前节点的前一个节点
while(cur != null){
if (cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return dummy.next; // 虚拟节点的next节点作为返回值
}
思路2:只使用pre指针,不需要虚拟头节点
不创建虚拟头节点,先对头节点进行处理,即找到第一个符合要求的节点作为头节点,当然此处仍旧需要pre节点。
Java代码如下:
public ListNode removeElements(ListNode head, int val) {
while(head!=null && head.val != val){ // 找到第一个值不等于val的节点作为头节点
head = head.next;
}
if(head == null){
return head;
}
ListNode cur = head.next; // 在pre指针的协助下完成节点的删除
ListNode pre = head;
while(cur != null){
if (cur.val == val){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return head; // 直接返回头节点
}
思路3:两者都不需要
继承思路二中对于头节点的操作,即不创建虚拟头节点。同时不使用pre节点,而只使用cur和cur.next完成节点的删除操作。
Java代码如下:
public ListNode removeElements(ListNode head, int val){
while(head!=null && head.val == val){ // 找到第一个符合要求的头节点
head = head.next;
}
if(head == null){
return head;
}
ListNode cur = head;
while(cur.next!=null){
if(cur.next.val == val){ // cur节点相当于思路2中的pre节点,
cur.next = cur.next.next; // cur.next相当于思路2中cur节点
}else{
cur = cur.next;
}
}
return head;
}