[leetCode]剑指 Offer 18. 删除链表的节点
单指针 一
这个解法和原著思路类似:
- 找到要删除结点的位置p
- 将p的下一个结点的值复制给p
- 删除p的下一个结点
- 由于没有处理尾部结点,最后需要判断:
如果删除的是尾部结点,则找到尾部结点的前一个结点,再将尾部结点删除
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
ListNode p = head;
while(p != null){
if(p.val == val && p.next !=null){
p.val = p.next.val;
p.next = p.next.next;
break;
}
p = p.next;
}
//删除尾部结点
if(p == null){
p = head;
while(p.next.val != val){
p = p.next;
}
p.next = null;
}
return head;
}
}
单指针 二
如果删除的是头结点则返回其下一个结点;通过遍历找到要删除结点的前一个结点的位置,然后将需要删除的结点删除。
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
//删除的结点为头节点
if(head.val == val) return head.next;
ListNode p = head;
//移动指针找到要删除结点的前一个结点
while(p.next.val != val){
p = p.next;
}
p.next = p.next.next;
return head;
}
}
递归
链表中每个结点都代表一个新的链表,所以可以将此题转化为删除某个链表中的头结点:
- 如果要删除的头结点所在链表为空则返回空
- 如果当前链表的头结点就是要删除结点则返回该链表头结点的下一个结点,否则进行递归删除
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
if(head.val == val) return head.next;
head.next = deleteNode(head.next,val);
return head;
}
}
双指针
使用双指针从前往后遍历,使用pre记录要删除结点的前一个结点,使用cur记录需要删除的结点,对删除结点为头节点的情况进行特殊处理。
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
ListNode pre = head, cur = pre.next;
//处理删除结点为头节点的情况
if(pre.val == val) return cur;
while(pre != null){
if(cur.val == val){
pre.next = cur.next;
break;
}
pre = cur;
cur = cur.next;
}
return head;
}
}