力扣题目
203. 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点
节点ListNode类
public class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
方法1
- 思路:
- 遍历链表,当节点的值为val时,就放弃该节点,这里就需要找到该节点的前一个节点pre,然后pre.next = pre.next.next
- 这里有一个疑问:怎么才是放弃该节点
- 链表是头节点开始,串起来一个个元素,组成链表。当某个节点不指向该节点时,就是链表把它给放弃了。
public class Solution {
/**
* 1、当链表为空,直接返回
* 2、依次遍历链表,当p节点的值 == val,则跳过p.next节点,即:p.next = p.next.next;
* 3、当p节点的值 != val,则继续遍历
* 4、最后对头节点进行特殊处理。因为开始时就用p.next,没有处理头节点,所以补上
* 我一直想拿到该节点的前一个节点,还想定义一个ListNode pre去拿。实际上,直接去对p.next值去比较,不就相当于变相拿到了pre,
* 这个pre就是p。
* @param head
* @param val
* @return
*/
public ListNode removeElements(ListNode head, int val) {
//如果链表为空
if(head == null){
return null;
}
//然后依次遍历链表
ListNode p = head;
while(p.next != null){
if(p.next.val == val){
p.next = p.next.next;
}else{
p = p.next;
}
}
//特殊处理头节点
if(head.val == val){
head = head.next;
}
return head;
}
}
方法2
- 引入虚拟头节点,然后对链表进行遍历,比较值是否与val相等。
- 这里引入虚拟头节点的好处是:可以不用对head为null进行特殊处理。
public class Solution {
public ListNode removeElements(ListNode head, int val){
//引入虚拟头节点
ListNode newHead = new ListNode();
//虚拟头节点,指向真正的头节点head
newHead.next = head;
//定义p,它也指向真正的头节点,移动它,去遍历链表
ListNode p = newHead;
while(p.next != null){
if(p.next.val == val){
p.next = p.next.next;
}else{
p = p.next;
}
}
return newHead.next;
}
}
方法3
class Solution {
public ListNode removeElements(ListNode head, int val) {
//虚拟头节点
ListNode newHead = new ListNode();
//虚拟头节点,用tail去移动(新链表)
ListNode tail = newHead;
//头节点,用p去移动(旧链表)
ListNode p = head;
//当 当前节点不为null,先用中间变量保留下一个节点
//当前节点的val不等于要查找的val,那就让当前节点p的next置为null,就是从旧链表中删除了当前节点,
//再将新链表的tail.next指向当前节点p,即新链表加上了节点p,并将tail后移一位,验证下一个节点
//然后把中间变量temp赋值给当前节点p,即p向后移动了一位。因为if中将p.next置为了null,所以才用中间变量进行赋值
//开启下一个节点验证
//newHead作为新节点的虚拟头指针,顺利串起了非val的节点。而且每次遍历旧链表,它的非val元素都会被丢弃,这样
//空间复杂度还是O(1),没有申请新的内存空间。
//最后返回虚拟头节点的next,即为真正的头节点
while(p != null){
ListNode tmp = p.next;
if(p.val != val){
p.next = null;
tail.next = p;
tail = p;
}
p = tmp;
}
return newHead.next;
}
}