本人是刷《代码随想录》这本书时记录一下自己的学习笔记
力扣203
题目中涉及链表的删除,删除链表的节点有两种方式:
1、没有头结点的删除;
2、与头结点的删除;
没有头结点的删除:
第一个元素的删除逻辑和其他节点删除元素逻辑不一样,第一个元素删除是把第一个节点往下一个移动,如图(图为《代码随想录》里的图)
其他节点删除逻辑:改变next指针,如图
public ListNode removeElements(ListNode head, int val) {
//注意是while循环,因为如果是1,1,1,1,1,这样连续的链表就得全部删除
while(head!=null && head.val==val){
head = head.next;
}
//本来是要设定两个节点的,一个是删除节点的前一个节点
//一个是待删除节点,但因为上面已经检验过head了,所以只需要设定一个节点就行
ListNode f = head;
while(f!= null && f.next != null){
if(f.next.val == val){
f.next = f.next.next;
}else{
f = f.next;
}
}
return head;
}
有头结点的删除:
头结点的删除就遵循一个删除逻辑,改变节点的next指向
public ListNode removeElements(ListNode head, int val) {
ListNode s = new ListNode(-1,head); //定义一个头结点
ListNode p1 = s; //记录前一个节点,为了删除
ListNode p2 = s.next; //记录节点,遍历节点
while(p2!=null){
if(p2.val==val){
p1.next = p2.next; //改变链表,跳过被删除的节点
p2 = p2.next; //更新p2节点,p1节点不需要更新,因为p1节点后面被删除了
}else{
p1 = p1.next; //更新p1节点
p2 = p2.next; //更新p2节点
}
}
return s.next;
}
递归写法
思路:
递归函数返回的是完成删除的链表:
1、如果当前是删除节点,应该返回上一层节点的递归结果;
2、如果当前不是删除节点,应该返回当前节点;
public ListNode removeElements(ListNode head, int val) {
if(head==null){
return null;//遍历到最后一个节点的next返回null
}
if(head.val == val){
return removeElements(head.next,val); //跳过这个节点,返回下一个节点
}else{
head.next = removeElements(head.next,val);//链接上一个返回的节点
return head;//返回此节点
}
}
总结
本文实现删除链表两种操作:
一种是带有头结点:需要准备两个节点,记录一个记录待删除节点的前一个节点,记录一个记录待删除节点;
一种是不带有头结点:执行逻辑分为两个,一个是首结点的删除,一个是其他节点的删除。