目录
题目
LCR 136. 删除链表的节点 - 力扣(LeetCode)
思路
设置两个指针:
- prev:指向当前处理节点的前一个节点
- curr:指向当前正在处理的节点
遍历链表:
- 如果 curr->val == val(当前节点的值等于目标值),则执行删除操作:
- prev->next = curr->next(将前一个节点直接连接到当前节点的下一个节点)
- 此时 prev 不变,curr 移动到下一个节点
- 如果 curr->val != val(当前节点的值不等于目标值),则两个指针都向前移动:
- prev = curr
- curr = curr->next
处理头节点特殊情况:
- 如果头节点的值等于目标值,需要特殊处理
- 一种方法是使用虚拟头节点(dummy node),将其next指向原始头节点
- 这样可以统一处理所有节点,包括头节点
返回结果:
- 如果使用了虚拟头节点,返回 dummy->next
- 否则,需要特殊处理头节点,并返回可能更新的头节点
双指针方法的优势:
- 能够在一次遍历中完成删除操作
- 可以方便地处理链表中的节点删除,因为删除节点需要修改前一个节点的next指针
- 代码逻辑清晰,易于理解和实现
读者可能出现的错误写法
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
//双指针方法
//基础判断
if(!head)
{
return head;
}
//定义双指针
ListNode* prev = head;
ListNode* curr = head->next;
while(curr)
{
prev = prev->next;
curr = curr->next;
if(curr->val == val)
{
prev->next = curr->next;
}
}
return head;
}
};
没有处理头节点等于目标值的情况:如果头节点的值等于val,您的代码不会删除它。
指针移动逻辑错误:在循环中,您先移动了prev和curr指针,然后才检查值,这会导致指针错位。正确的做法是先检查值,然后根据情况决定是否移动指针。
空指针访问:在while循环中,您先移动了curr指针,然后访问curr->val,如果curr变成nullptr,这会导致空指针访问。
prev指针更新错误:您将prev直接设为prev->next,这样prev和curr就指向了同一个节点,无法正确删除节点。
正确写法
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
//双指针方法
ListNode * dummy = new ListNode(0);
dummy->next = head;
//定义双指针
ListNode* prev = dummy;
ListNode* curr = head;
while(curr)
{
if(curr->val == val)
{
prev->next = curr->next;
curr = curr->next;
}
else
{
prev = prev->next;
curr = curr->next;
}
}
ListNode* newhead = dummy->next;
return newhead;
}
};